283. 移动零
https://leetcode.cn/problems/move-zeroes/description/?envType=study-plan-v2&envId=top-100-liked
public void moveZeroes(int[] nums) {
int r = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0){
int temp = nums[r];
nums[r] = nums[i];
nums[i] = temp;
r++;
}
}
}
总结:一个指针去记录放非0的位置,一个指针去遍历
11. 盛最多水的容器
https://leetcode.cn/problems/container-with-most-water/description/?envType=study-plan-v2&envId=top-100-liked
public int maxArea(int[] height) {
int i = 0 , j = height.length - 1;
int maxRain = 0;
while (i < j){
maxRain = height[i] < height[j] ?
Math.max(maxRain , getRain(height ,i++,j)) :
Math.max(maxRain , getRain(height,i,j--));
}
return maxRain;
}
public int getRain(int[] height, int i,int j){
return (j - i) * Math.min(height[i],height[j]);
}
总结:使用双指针,总体思想就是先让指针在左右边界,然后每次指针往里收缩,收缩哪个呢,收缩二者矮的那个,因为收缩矮的,下个面积可能变大,如果收缩高的,下个面积不变(收缩了之后高度一样)或变小(收缩之后高度变小)(ps:如果收缩之后高度变大了,由于有之前的短板的存在,所以木桶效应,还是面积会变小)
15. 三数之和
https://leetcode.cn/problems/3sum/description/?envType=study-plan-v2&envId=top-100-liked
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
List<List<Integer>> resList = new ArrayList<>();
for (int k = 0; k < nums.length - 2; k++) {
if (nums[k] > 0) break;
if (k > 0 && nums[k] == nums[k-1]) continue;
int i = k + 1 , j = nums.length - 1;
while (i < j){
int sum = nums[k] + nums[i] + nums[j];
if (sum > 0){
do{
j--;
}while (i < j && nums[j] == nums[j+1]);
}else if (sum < 0){
do {
i++;
}while (i < j && nums[i] == nums[i-1]);
}else {
resList.add(new ArrayList<Integer>(Arrays.asList(nums[k],nums[i],nums[j])));
do{
j--;
}while (i < j && nums[j] == nums[j+1]);
do {
i++;
}while (i < j && nums[i] == nums[i-1]);
}
}
}
return resList;
}
总结:关键点在于去重,这里使用的方法就是先排序了,排序之后通过指针可以很好解决去重(发现和上一个重复就再往中间移动), 最后犹豫不决先排序,步步逼近双指针!
42. 接雨水
https://leetcode.cn/problems/trapping-rain-water/description/?envType=study-plan-v2&envId=top-100-liked
public int trap(int[] height) {
int rain = 0;
// 左右指针:分别指向左右两边界的列
int left = 0;
int right = height.length - 1;
// 左指针的左边最大高度、右指针的右边最大高度
int leftMax = height[left];
int rightMax = height[right];
// 最两边的列存不了水
left++;
right--;
// 向中间靠拢
while (left <= right){
leftMax = Math.max(leftMax,height[left]);
rightMax = Math.max(rightMax,height[right]);
if (leftMax <= rightMax){
// 左指针的leftMax比右指针的rightMax矮
// 说明:左指针的右边至少有一个板子 > 左指针左边所有板子
// 根据水桶效应,保证了左指针当前列的水量决定权在左边
// 那么可以计算左指针当前列的水量:左边最大高度-当前列高度
rain += leftMax - height[left];
left++;
}else {
// 右边同理
rain += rightMax - height[right];
right--;
}
}
return rain;
}
总结:核心思想就是上面注释中说的那样,左最高和右最高,若从左往右遍历的话 会更新左最高,此时如果右最高比左最高大就说明这一列肯定有水,就加进去即可 这道题我会每天复习一遍
标签:11,15,nums,int,LeetCodeHot100,height,++,while,指针 From: https://www.cnblogs.com/jeasonGo/p/18065070