5.5 KiB
#数列-nsum问题
数组,找出和为 s 的两个数
暴力解法
class Solution {
public int[] twoSum(int[] nums, int target) {
int res[] = new int[2];
for(int i = 0; i < nums.length; i++){
for(int j = i + 1; j < nums.length; j++){
if(nums[i] + nums[j] == target){
res[0] = i;
res[1] = j;
break;
}
}
}
return res;
}
}
使用 hash表,2遍扫描
class Solution {
public int[] twoSum(int[] nums, int target) {
int res[] = new int[2];
Map<Integer, Integer> map= new HashMap<>();
for(int i = 0; i < nums.length; i++){
map.put(nums[i], i);
}
for(int i = 0; i < nums.length; i++){
int temp = target - nums[i];
if(map.containsKey(temp) && map.get(temp) != i){
res[0] = map.get(temp);
res[1] = i;
}
}
return res;
}
}
找出和为N+1的2个数
一个整数数列,元素取值可能是1~N(N是一个较大的正整数)中的任意一个数,相同数值不会重复出现。
设计一个算法,找出数列中符合条件的数对的个数,满足数对中两数的和等于N+1。
复杂度最好是 O(n) ,如果是 O(n2)则不得分。
分析:列出所有的数对,如输入15,输出【1,14】【2,13】【3,12】。。。
int print_sequence_sum(int n)
找出和为m的2个数
输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。 例如输入数组【1、2、4、7、11、15=和数字15。由于4+11=15,因此输出4和11。
//返回0找到,返回-1没找到
int findaddends(int *data,int length,int sum,int *a,int *b);
分析:
数组升序排列,查找可用二分查找,时间复杂度O(logn),这样问题就变成了找其中一个加数的问题,复杂度为N*logN
巧妙解法:数组2端向中间扫描,复杂度O(N)
求子数组的最大和(最大字段和)
输入一个整形数组,数组里有正数也有负数。 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。 求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5 ,和最大的子数组为3, 10, -4, 7, 2 ,因此输出为该子数组的和18。
- 蛮力法 fmax(i,j) 找出最大的值,3重循环 ,复杂度 0(n^3)
- maxendindhere保存当前累加的和,如果<0,就把maxendinghere清零 , max保存最终的最大和
int maxSumOfVector(int *data,int length){
int max=0;
int maxendinghere = 0;
if(data==NULL || length<=0){
return 0;
}
for(int i=0;i < length, i++){
maxendinghere+=data[i];
if(maxendinghere<0){
maxendinghere=0;
continue;
}
if(maxendinghere>max){
max=maxendinghere;
}
}
return max;
}
和为n连续正数序列
题目:输入一个正数n,输出所有和为n连续正数序列。
例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。
print_continuous_sequence_sum(int n)
思路一:枚举法。从1开始一直加到等于n,再从2开始。。一直到 n/2+1,在每一轮,都要逐步比较。复杂度O(N^2)
思路二: a[small,big] sum[small,big]>N small往前移动,否则,big往前移动。 O(N) 复杂度搞定
求连续子数组和为m的组合
数组 [2,3,1,2,4,3]求连续子数组sum=7, 结果[1,2,4] [3,4]
- 暴力遍历
- 滑动窗口, 左指针,右指针
if sum<k && r<len{
sum+=arr[r]
r++
}else{
sum -= arr[l]
l++
}
和为m的组合
编程求解:输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来.
如: n=10,m=25;可能的组合有【】【】【】【】
print_sum_detials(int n , int sum)
动态规划(类似背包问题)
- 划分问题
- 选择状态
- 状态转移方程
- 规划方程
钞票面值100,50,20,10,5,2,1 元,求支付628元最少需要几张钞票
思路: 贪心算法
若干个数的和与M最为接近
给定一个实数数组,按序排列(从小到大),从数组从找出若干个数,使得这若干个数的和与M最为接近,描述一个算法,并给出算法的复杂度。
数组分隔成和相等的2个子集
给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等 (eetcode 416, 难度中等)
思路: 动态规划
n个骰子的点数
把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。 输入n,打印出S的所有可能的值出现的概率。
如n=1,值【1,2,3,4,5,6】每个概率是 1/6
如n=2,值【1~12】 概率。。
一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
比如{3,2,4,3,6} 可以分成{3,2,4,3,6} m=1; {3,6}{2,4,3} m=2 {3,3}{2,4}{6} m=3 所以m的最大值为3