1-两数之和
给定一个整数数组
nums和一个整数目标值target,请你在该数组中找出 和为目标值target的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
思路:本题由于不能排序,如果用双指针相当于暴力解法,先定左指针位置,右指针遍历,然后依次换左指针位置。 因为输出数字的位置,所以不能直接排序,若能排序 直接可以使用双指针。
java
class Solution {
public int[] twoSum(int[] nums, int target) {
int l=0,r=nums.length-1;
for(l=0;l<nums.length;l++){
while(l<r){
if(nums[l]+nums[r]==target){
return new int[]{l,r};
}
r--;
}
r=nums.length-1;
}
return new int[0];
}
}
细节注意: 注意返回值 return new int [ ] { l,r} 为新建一个int数列,值为l,r
return new int [ 0 ] 指返回长度为0的int数列。不能直接返回 null,否则会出现NullPointerException错误
283-移动零
给定一个数组
nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums =[0,1,0,3,12] 输出: [1,3,12,0,0]示例 2:
输入: nums =[0] 输出:[0]
**思路:**使用左右指针 i 和 j ,初始都在最左端,j一直向右前进遇到0就跳过,遇到非0就与i交换值,每换一次i就向右移动一次。这样j可以遍历完使用的元素去找非0,i的位置始终是0 等j找到就交换。
java
class Solution {
public void moveZeroes(int[] nums) {
int i=0,j=0;
while(j<nums.length){
if(nums[j]!=0){
int swap=nums[i];
nums[i]=nums[j];
nums[j]=swap;
i++;
}
j++;
}
}
}
细节注意:
int i=0,j=0; 需要分开定义,不能是int i,j=0;
开头为void,则不需要返回值;如果为 int [ ] ,则直接返回 return nums;
11-盛最多水的容器
给定一个长度为
n的整数数组height。有n条垂线,第i条线的两个端点是(i, 0)和(i, height[i])。找出其中的两条线,使得它们与
x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。
输入:[1,8,6,2,5,4,8,3,7] 输出:49 输入:height = [1,1] 输出:1
思路: 使用左右指针两端开始遍历,由于取面积最大(面积最大取决于最小的那个),所以需要移动最小的那个,即 左指针右移 右指针左移,直到相等结束。每移一次算一下面积,取最大值。
java
class Solution {
public int maxArea(int[] height) {
int l=0,r=height.length-1;
int max=0;
while(l<r){
int area=Math.min(height[l],height[r])*(r-l);
max=Math.max(area,max);
if(height[l]<height[r]){
l++;
}else{
r--;
}
}
return max;
}
}
细节注意:
Math.min() 和 Math.max() 可以直接求最大最小。
15-三数之和
给你一个整数数组
nums,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且j != k,同时还满足nums[i] + nums[j] + nums[k] == 0。请你返回所有和为0且不重复的三元组。注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]] 解释: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。 nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。 nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。 不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。 注意,输出的顺序和三元组的顺序并不重要。 示例 2: 输入:nums = [0,1,1] 输出:[] 解释:唯一可能的三元组和不为 0 。 示例 3: 输入:nums = [0,0,0] 输出:[[0,0,0]] 解释:唯一可能的三元组和为 0
**思路:**先排序,由于三个数字各不相同,先定一个数nums[ i ],然后取剩下两个之和为 -nums[ i ]即可。用双指针从i之后的两端遍历就行,当l和r相等时结束。但是要注意出现重复的情况(即i会重复, l或r在移动过程中也会重复。先进行操作,在移动之后若与上一个相等,则跳过。)
java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
int l=0;
List<List<Integer>> res = new ArrayList<>();
for(int i=0;i<nums.length;i++){
if (i > 0 && nums[i] == nums[i - 1]) continue;//跳过i重复的元素
l=i+1;int r=nums.length-1;int target=-nums[i];
while(l<r){
if(nums[l]+nums[r]==target){
res.add(Arrays.asList(nums[i], nums[l], nums[r]));
l++;
r--;
// 跳过重复元素
while (l < r && nums[l] == nums[l - 1]) l++;
while (l < r && nums[r] == nums[r + 1]) r--;
}else if(nums[l]+nums[r]>target){
r--;
}else if(nums[l]+nums[r]<target){
l++;
}
}
}
return res;
}
}
细节注意:
1、使用双指针必须排序Arrays.sort(xx);,才能发挥优势,两指针能比较 才能专门进行移动
2、将元素以List形式存进res列表,res.add(Arrays.asList(nums[i], nums[l], nums[r]))
3、每次执行r需要重置,再放在最右端