2022年3月23日 作者 zeroheart

算法入门第三天

双指针

「算法」 – 学习计划 – 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com)s

283. 移动零

本题的要领是双指针可以做到o(1),只遍历一次,36d1ac5d689101cbf9947465e94753c626eab7fcb736ae2175f5d87ebc85fdf0-283_2.gif (1280×720) (leetcode-cn.com)可以看这个动图

/**
 283. 移动零

 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

 请注意,必须在不复制数组的情况下原地对数组进行操作。



 示例 1:

 输入: nums = [0,1,0,3,12]
 输出: [1,3,12,0,0]
 示例 2:

 输入: nums = [0]
 输出: [0]


 提示:

 1 <= nums.length <= 10^4
 -2^31 <= nums[i] <= 2^31 - 1

 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/move-zeroes
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 * @author zeroheart
 *
 */
public class Question283 {
    public static void moveZeroes(int[] nums) {
        int j = 0;
        // 两个指针,一次遍历,可以看这个图例 https://pic.leetcode-cn.com/36d1ac5d689101cbf9947465e94753c626eab7fcb736ae2175f5d87ebc85fdf0-283_2.gif
        // i 往前走,遇到非0的就和0的位置的指针j交换,j++
        for(int i = 0; i < nums.length; i++){
            if(nums[j] != 0){
                // 优化,去掉这个也可以,nums[i]!=0就直接交换,不过有多余的次数
                j++;
            }else if(nums[i]!=0 && nums[j] == 0){
                int temp = nums[i];
                nums[i] = nums[j];
                nums[j] = temp;
                j++;
            }

        }
        Arrays.stream(nums).asLongStream().forEach(System.out::print);
    }


    public static void main(String[] args) {
//        moveZeroes(new int[]{0,0,1});
//        moveZeroes(new int[]{0,1,0,3,12});
        moveZeroes(new int[]{1,0,1,0,3,12});
    }
}

167. 两数之和 II – 输入有序数组

本题之前都做过,主要依据是数组本身有序,所以可以首尾双指针,两数之和大的,移动尾部指针,小的移动头部指针。

/**
 167. 两数之和 II - 输入有序数组

 给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。

 以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

 你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

 你所设计的解决方案必须只使用常量级的额外空间。

 示例 1:

 输入:numbers = [2,7,11,15], target = 9
 输出:[1,2]
 解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
 示例 2:

 输入:numbers = [2,3,4], target = 6
 输出:[1,3]
 解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
 示例 3:

 输入:numbers = [-1,0], target = -1
 输出:[1,2]
 解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。


 提示:

 2 <= numbers.length <= 3 * 10^4
 -1000 <= numbers[i] <= 1000
 numbers 按 非递减顺序 排列
 -1000 <= target <= 1000
 仅存在一个有效答案

 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 * @author zeroheart
 *
 */
public class Question167 {
    public int[] twoSum(int[] numbers, int target) {
        // 因为是有排序的,所以可以用双指针来处理
        int j = numbers.length-1;
        int i = 0;
        while (i < j){
            int r = numbers[i] + numbers[j];
            if( r == target){
                return new int[]{i+1, j+1};
            }else if(r > target){
                j--;
            }else {
                i++;
            }
        }
        return null;
    }
}