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;
}
}