剑指offer第57题 找和为s的数字(双指针和尺取法)



问题一:和为s的两个数

问题描述:

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]

示例 2:

输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]

解题思路:

  由于数组是递增的,所以可以使用双指针的解法,刚开始两个指针分别指向数组的头和尾,当和小于target时左指针向有移动,取一个更大的值;当和大于target时右指针向做移动,取一个更小的值。
  这题不要想得太多而用尺取法,尺取法是用于寻找一个范围,不适用与这一题。

代码如下:

public int[] twoSum(int[] nums, int target) {
    
    
	int l = 0;
	int r = nums.length-1;
	while(l<r) {
    
    
		if(nums[l]+nums[r]<target) {
    
    
			l++;
		}else if(nums[l]+nums[r]>target) {
    
    
			r--;
		}else
			break;
	}
	return new int[] {
    
    nums[l],nums[r]};
}

提交结果:
在这里插入图片描述



问题二:和为s的连续正数序列

问题描述:

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例 1:

输入:target = 9
输出:[[2,3,4],[4,5]]

示例 2:

输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

解题思路:

  这题求的是一个序列,可以看作一个范围;所以可以使用尺取法进行解题。

有关尺取法的讲解可以参考文章:尺取法

代码实现:

    public static int[][] findContinuousSequence(int target) {
    
    
    	if(target<3) return new int[0][0];
    	int end = target/2 +1;
    	List<int[]> list = new ArrayList<int[]>();  //用于存储结果集
    	int l = 1;
    	int r = 2;
    	while(l<r && r<=end) {
    
      //注意r是可以等于end的。
    		if(sum(l,r)>target) {
    
    
    			l++;
    		}else if(sum(l,r)<target) {
    
    
    			r++;
    		}else {
    
    
    			//将找到的序列封装成数组
    			int[] temp = new int[r-l+1];
    			int index = 0;
    			for(int i=l; i<=r; i++)
    				temp[index++] = i;
    			list.add(temp);
    			l++;
    		}
    	}
    	//将list转换为二维数组
    	int[][] res = new int[list.size()][];
    	for(int i=0; i<list.size(); i++) {
    
    
    		res[i] = list.get(i);
    	}
    	return res;
    }

    //求l 到 r 的整数序列的和
	private static int sum(int l, int r) {
    
    
		int s = 0;
		for(int i=l; i<=r; i++) {
    
    
			s += i;
		}
		return s;
	}

提交结果:
在这里插入图片描述

这题可以优化一下:用等差数列求和公式进行求和:

    //求l 到 r 的整数序列的和
	private static int sum(int l, int r) {
    
    
		int s = 0;
		s = (l+r)*(r-l+1)/2;
		return s;
	}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/HC199854/article/details/109380268