2022年3月23日
算法入门第三天
双指针
「算法」 – 学习计划 – 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com)s
本题的要领是双指针可以做到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 - 输入有序数组 给你一个下标从 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; } }