数组要注意越界问题
一般转化为有序,但是如果是返回位置而不是数的集合,就要用到hashtable
1.申请一个hash_table unordered_map<int, int> hash; 2.遍历数组,令num = target - nums[i]; 2.1.如果num已经在hash_map中了,那就返回hash[num]和i 2.2.否则把nums[i]-i存在hash_map
for (int i = 0; i < nums.size(); i++) { int num = target - nums[i]; if (hash.find(num)!=hash.end()) //存在 return {hash[num],i}; hash[nums[i]] = i; } return result;给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。
vector<vector<int> > combinationSum(vector<int> &candidates, int target) { sort(candidates.begin(), candidates.end());//1.排序 vector<vector<int> > v; vector<int> tmp; combinationSum(candidates, target, v, tmp, 0);//调用递归函数 return v; } void combinationSum(vector<int>& candidates, int target, vector<vector<int> >& v, vector<int>& tmp, int begin) { if (target==0) //1.只有target恰好减为0时,才加入v; { v.push_back(tmp); return; } //每一层都有一个for,以此来找最终符合target==0条件的tmp for (int i = begin; i != candidates.size() && target >= candidates[i]; ++i) //从begin开始遍历 { tmp.push_back(candidates[i]); //只要target >= candidates[i],就往下一层递归 //target 不断减小,combination不断加入新的值,begin在++ combinationSum(candidates, target - candidates[i], v, tmp, i); tmp.pop_back();//下一层不满足target=0,上一层就pop_back, } }给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。
vector<vector<int> > combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end());//1.排序 vector<vector<int> > v; vector<int> tmp; solver(candidates, target, v, tmp, 0);//2.递归 return v; } void solver(vector<int>& candidates, int target, vector<vector<int> >& v, vector<int>& tmp, int beg) { if(target==0)//3.最终恰好减为1,tmp才符合条件 { v.push_back(tmp);//3.1加入v return; } for (int i=beg; i<candidates.size() && candidates[i]<=target; i++)//4.每一递归层,满足candidates[i]<=target,则继续for遍历 { if (i!=beg && candidates[i]==candidates[i-1]) //**4.1 保证每个数字在每个组合中只能使用一次 continue; tmp.push_back(candidates[i]);//4.2 //**4.3. 递归, target-candidates[i] ,i+1保证每个数字在每个组合中只能使用一次 solver(candidates, target-candidates[i], v, tmp , i+1); tmp.pop_back();//4.3 保证每层只push_back一个元素 } }找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有1 - 9的正整数,并且每种组合中不存在重复的数字。 注:0~9中k个数和为n,就是在 组合总和II 的基础上, 限制了0<target<50; 1<k<10; 数组中的元素为[1~9],并且无重复; 并且限制了元素个数为k。
vector<vector<int>> combinationSum3(int k, int n) { vector<vector<int> > v; vector<int> tmp; //1.因为是已排序,不用再排序,可以看成0~9,只不过从1开始算,则是为了保证下标和数值是一致的 help(k, n, v, tmp, 1); return v; } void help(int k, int target, vector<vector<int> >& v, vector<int>& tmp, int beg) { if (target < 0 || k > 9|| beg > 10 || tmp.size() > k ) //2.特殊条件判断 return; if (target == 0 && tmp.size() == k) //3.恰好target == 0,并且同时tmp.size() == k才放入v { v.push_back(tmp); return; } for (int i = beg; i < 10 && i<=target; i++) //4.i<=target { tmp.push_back(i); help(k, target - i, v, tmp, i + 1); //5.递归;i+1,保证不重复 tmp.pop_back(); } }“`
给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。
dp[i]:以i为最后一个元素,最大 连续子数组和:dp[i] = nums[i] + max(dp[i - 1] , 0 );,可以看出只要maxsum>0,他就是有价值的。 “`cpp int maxSubArray(vector& nums) { int n = nums.size(); vector dp(n,0); dp[0] = nums[0]; int maxsum = dp[0]; for(int i = 1; i < n; i++) { dp[i] = nums[i] + max(dp[i - 1] , 0 ); maxsum = max(maxsum, dp[i]); } return maxsum; }
