1-leetcode移动零
注意:√
- 思路之前见过,不过需要复习
- 简单来说就是先把不是0的赶到左边去,然后把后续全部设置为0
public void moveZeroes(int[] nums) {
int n = nums.length;
if (n == 1){
return;
}
int low = 0;
int high = 0;
while (high < n){
if (nums[high] != 0){
nums[low] = nums[high];
low++;
}
high++;
}
for (int i = low; i<n; i++){
nums[i] = 0;
}
}
2-leetcode盛最多水的容器
注意:×√
- 看了接雨水以后,这个确实要简单一点,注意是矩形面积的计算
public int maxArea(int[] height) {
int n = height.length;
int left = 0;
int right = n-1;
int res = 0;
while (left<right){
res = Math.max(res, Math.min(height[left], height[right])* (right-left));
if (height[left] <= height[right]){
left++;
}else {
right--;
}
}
return res;
}
3-leetcode三数之和
注意:×
- 学习的是labuladong的方法,3sum转2sum
- 注意要先对数组排序,在2sum中操作的时候要注意
int total = nums[low] + nums[high]; int left = nums[low]; int right = nums[high];
- 注意整理的left和right用于后续的while判断,一定要注意while判断以后还需要进行指针的移动操作
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
Arrays.sort(nums);
int n = nums.length;
for (int i = 0; i < n; i++) {
List<List<Integer>> twoAns = twoSum(nums, i + 1, 0 - nums[i]);
for (List<Integer> twoAn : twoAns) {
twoAn.add(nums[i]);
ans.add(twoAn);
}
while (i<n-1 && nums[i] == nums[i+1]){
i++;
}
}
return ans;
}
private List<List<Integer>> twoSum(int[] nums, int start, int target) {
List<List<Integer>> ans = new ArrayList<>();
int low = start;
int high = nums.length - 1;
while (low<high){
int total = nums[low] + nums[high];
int left = nums[low];
int right = nums[high];
if (total > target){
while (low<high && nums[high-1]==right){
high--;
}
high--;
} else if (total < target) {
while (low<high && nums[low+1]==left){
low++;
}
low++;
}else {
List<Integer> an = new ArrayList<>();
an.add(left);
an.add(right);
ans.add(an);
while (low<high && nums[high-1]==right){
high--;
}
while (low<high && nums[low+1]==left){
low++;
}
high--;
low++;
}
}
return ans;
}
4-leetcode接雨水
注意:×
- 传说中的接雨水,
trap1
是用的备忘录,trap
用的是双指针 - 很巧妙的思路,注意
base case
中的初始值,以及遍历的方向
public int trap1(int[] height) {
int n = height.length;
int[] leftMax = new int[n];
int[] rightMax = new int[n];
// base case
leftMax[0] = height[0];
rightMax[n-1] = height[n-1];
for (int i = 1; i < n; i++) {
leftMax[i] = Math.max(leftMax[i-1], height[i]);
}
for (int i = n-2; i >= 0; i--) {
rightMax[i] = Math.max(rightMax[i+1], height[i]);
}
int res = 0;
for (int i = 1; i < n-1; i++) {
res = res+ Math.min(leftMax[i], rightMax[i])-height[i];
}
return res;
}
public int trap(int[] height) {
int n = height.length;
if (n<3){
return 0;
}
int leftMax = height[0];
int rightMax = height[n-1];
int left = 0;
int right = n-1;
int res = 0;
while (left<right){
leftMax = Math.max(leftMax, height[left]);
rightMax = Math.max(rightMax, height[right]);
if (leftMax<rightMax){
res = res+ leftMax-height[left];
left++;
}else {
res = res + rightMax-height[right];
right--;
}
}
return res;
}