利用双指针技巧来解决七道与数组相关的题目。
两数之和 II - 输入有序数组: 给定一个按升序排列的数组,找到两个数使它们的和等于目标值。可以使用双指针技巧,在数组两端设置左右指针,根据两数之和与目标值的大小关系移动指针。
删除有序数组中的重复项: 给定一个有序数组,原地删除重复出现的元素,使每个元素只出现一次,并返回新的长度。利用双指针技巧,一个指针用于遍历数组,另一个指针指向新数组的末尾。
移除元素: 给定一个数组和一个值,原地移除数组中所有等于该值的元素,返回新数组的长度。同样利用双指针技巧,一个指针用于遍历数组,另一个指针用于记录非目标值的位置。
移动零: 给定一个数组,将所有的 0 移动到数组的末尾,同时保持非零元素的相对顺序。使用双指针技巧,一个指针遍历数组,另一个指针记录非零元素的位置,并将非零元素依次移到前面。
反转字符串: 反转给定的字符串。利用双指针技巧,一个指针从数组的开头向后移动,另一个指针从数组的末尾向前移动,依次交换两个指针指向的元素。
最长回文子串: 找到给定字符串中的最长回文子串。作者通过介绍中心扩散法,结合双指针技巧,在遍历过程中寻找回文子串的中心点。
删除排序链表中的重复元素: 删除排序链表中重复的元素,使得每个元素只出现一次。使用双指针技巧,一个指针遍历链表,另一个指针负责删除重复元素
一、两数之和
题目描述
给你一个下标从 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 * 104
-1000 <= numbers[i] <= 1000
numbers
按 非递减顺序 排列-1000 <= target <= 1000
- 仅存在一个有效答案
解题思路及代码
定义双指针分别为数组头部l,尾部r,因为数组有序,如果两数相加大于target,右指针左移,反之亦然。
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l=0,r=numbers.length-1;
while(l<r){
if(numbers[l]+numbers[r]==target){
return new int[]{l+1,r+1};
}else if(numbers[l]+numbers[r]<target){
l++;
}else{
r--;
}
}
return new int[]{};
}
}
结果展示
二、删除有序数组的重复项
题目描述
给你一个 非严格递增排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组 int[] expectedNums = [...]; // 长度正确的期望答案 int k = removeDuplicates(nums); // 调用 assert k == expectedNums.length; for (int i = 0; i < k; i++) { assert nums[i] == expectedNums[i]; }
如果所有断言都通过,那么您的题解将被 通过。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2,并且原数组 nums 的前两个元素被修改为 1, 2
不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4] 输出:5, nums = [0,1,2,3,4] 解释:函数应该返回新的长度5
, 并且原数组 nums 的前五个元素被修改为0,1, 2, 3, 4
。不需要考虑数组中超出新长度后面的元素。
提示:
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums
已按 非严格递增 排列
解题思路及代码
class Solution {
public int removeDuplicates(int[] nums) {
int l=0,r=1;
while(r<nums.length){
if(nums[l]!=nums[r]){
l++;
nums[l]=nums[r];
}
r++;
}
return l+1;
}
}