2021/03/08阿里在线笔试问题总结
两道题目,限时一小时,从零到一完全实现。
第一题:https://leetcode-cn.com/problems/kth-missing-positive-number/
第二题:https://leetcode-cn.com/problems/profitable-schemes/
题目一:
n张卡片,无重复值,升序排列,想知道从第一张卡片的值开始第k个在卡片中未出现的正整数为多少,并进行返回
输入输出:
func main() { T, nArr, kArr, ans := ReadData1() res := make([]int,0) for i:=0;i<T;i++{ tmp := solve1(nArr[i],kArr[i],ans[i]) res = append(res, tmp) } for i:=0;i<(len(res));i++{ fmt.Println(res[i]) } } func ReadData1()(int, []int, []int, [][]int){ var ( T int n,k int tmp int ans [][]int ) fmt.Scanln(&T) nArr, kArr := make([]int,T),make([]int,T) for i:=0;i<T;i++{ fmt.Scanln(&n, &k) nArr[i] = n kArr[i] = k res := make([]int,n,n) for j :=0;j<n;j++{ fmt.Scan(&tmp) res[j] = tmp } ans = append(ans, res) } fmt.Println(ans,T,nArr,kArr) return T, nArr, kArr, ans }
核心方案:
使用map存放已有的数据值,如果从arr[0]累加,遇到map中有值,进行跳过处理
func solve1(n, k int,ans []int)int{ ansMap := make(map[int]bool, n) for i:=0;i<n;i++{ ansMap[ans[i]] = true } val := ans[0] for k > 0 { if _, ok := ansMap[val];!ok{ k-- } val++ } return val-1 }
题目二:
有m个任务,至多有n个工人,工人之间无差别,每个任务需要的工人数量为a[i],收益为b[i],要求每种方案总收益不少于p,
求有多少种可行的方案,其中:
每个文件输入第一行输入一个整数T(《=100》),代表有T组测试数据,接下来T组,每组第一行输入三个整数m,n,p代表任务的数量,
需要的最多工人数以及需要获得的最少利润,接下来输入m个整数,a[i]代表每一个任务所需的工人数量,输入m个整数,
b[i]代表每一个任务能获得的收益
case:
1
2 5 3
2 2
2 3
输出
2 //一二都做或者仅做第二个
输入输出:
type Case struct { M,N,P int Nums, Profile []int } func ReadData2()([]Case){ var ( T int m, n, p int tmp int ) fmt.Scanln(&T) cases := make([]Case, 0) for i:=0;i<T;i++{ fmt.Scanln(&m, &n, &p) caseTmp := Case{M:m,N:n,P:p,Nums: make([]int, m),Profile: make([]int, m)} res1 := make([]int,2) for k:=0;k<m;k++{ for j :=0;j<2;j++{ fmt.Scan(&tmp) res1[j] = tmp } caseTmp.Nums[k] = res1[0] caseTmp.Profile[k] = res1[1] } cases = append(cases, caseTmp) } //fmt.Println(cases) return cases }
方案:
暴力破解,求出所有可能的组合,进行判断
func backpack(val Case) int { cnt := 0 arr := make([]int, val.M, val.M) res := make([][]int,0) var sub func(n int) sub = func(n int) { if n >= val.M{ tmp := make([]int, len(arr)) copy(tmp, arr) res = append(res, tmp) return } arr[n] = 0 sub(n+1) arr[n] = 1 sub(n+1) return } sub(0) for i:=0;i<len(res);i++{ pro := 0 num := 0 for j := 0;j<len(res[i]);j++{ if res[i][j] == 1{ pro += val.Profile[j] num += val.Nums[j] } } if pro>=val.P && num < val.N{ cnt++ } } return cnt }
总结:第一题难度不高,但是自己写输入输出的确费点时间,一个小时根本不够用啊