本文主要是介绍和为s的两个数字VS和为s的连续正数序列(Java),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目:
输入一个递增排序的数组和一个数字s,在数组在查找两个数,使得它们的和正好是。如果有多对数字的和等于s,输出任意一对即可。
例如:输入数组{1、2、4、7、11、15}和数字15。由于4 + 11 = 15,因此输出4 和 11。
思路:
直观的思路:遍历数组两遍,即每一个数字和后面的数字相加看是否等于15,是直接返回,否则继续遍历直到找到或者遍历结束为止。时间复杂度O(n^2)。
最优解思路:定义两个指针p1和p2,p1指向1,p2指向15。p1 + p2 大于15,p2指针移动,p1 + p2 小于15,p1指针移动,直到p1 + p2 = 15,返回p1和p2。
代码实现:
public static ArrayList<Integer> findNumbersWithSum(int data[], int sum){ArrayList<Integer> list = new ArrayList<Integer>();if(data == null || data.length < 2){return list;}int p1 = 0; //指向数组首元素int p2 = data.length - 1; //指向数组末尾元素while(p2 > p1){if(data[p1] + data[p2] == sum){list.add(p1);list.add(p2);}else if(data[p1] + data[p2] > sum){p2--;}else{p1++;}}return list;
}
拓展题目:
输入一个整数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1 + 2 + 3 + 4 + 5 = 4 + 5 + 6 = 7 + 8 =15,所以结果打印出3个连续序列1~5,4~6和7~8。
思路:
定义两个指针p1和p2分别指向数组的第一个位置和数组的第二个位置,求序列的和,如果小于s,p2向后移动,继续就和,如果满足,打印当前p1和p2指向的序列片段,p2继续移动,此时序列的和会大于s,p1向前移动,判断序列和是否为s,如果小于s,p2向后移动,继续上面的判断,否则如果大于s,p1向前移动,在判断和,如果大于或者等于,或者小于,分别做对应的处理。等于的话:输出序列片段,p2向后移动;小于的话p2直接向后移动,再做判断;大于的话p1向后移动,再做判断。
代码实现:
public static ArrayList<ArrayList<Integer>> finfContinuousSequence(int sum){ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();if(sum < 3){ //因为至少含有两个数,故1+2=3,故sum > 3return list;}ArrayList<Integer> l = new ArrayList<Integer>();int small = 1;int big = 2;int middle = (1 + sum) / 2; //因为至少连续2个且顺序增加,所以取中间值int curSum = small + big;while(small < middle){if(curSum == sum){for(int i = small; i <= big; i++){l.add(i);}list.add(l);}while(curSum > sum && small < middle){curSum -= small;small++;if(curSum == sum){for(int i = small; i <= big; i++){l.add(i);}list.add(l);}}big++;curSum += big;}return list;
}
这篇关于和为s的两个数字VS和为s的连续正数序列(Java)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!