Day2--HOT100--283. 移动零,11. 盛最多水的容器,15. 三数之和
Day2–HOT100–283. 移动零,11. 盛最多水的容器,15. 三数之和
每日刷题系列。今天的题目是力扣HOT100题单。
双指针题目。
283. 移动零
思路【我】:
- 左指针指向第一个0
- 右指针从第一个0的下一个开始遍历到结尾。
- 当0,跳过
- 非0,和左指针交换。左指针++
class Solution {public void moveZeroes(int[] nums) {int n = nums.length;int left = n;// 左指针指向第一个0for (int i = 0; i < n; i++) {if (nums[i] == 0) {left = i;break;}}// 如果左指针不变,证明没有0,right指针大于n,不会进入这个循环// 右指针指向非0数,把左指针的0用右指针的值覆盖掉,右指针置为0for (int right = left + 1; right < n; right++) {if (nums[right] == 0) {continue;}nums[left++] = nums[right];nums[right] = 0;}}
}
思路【@灵艾山茶府】:
- 当右指针非0,交换左右指针,左指针++
- 隐含着:当前期左指针和右指针都非0的时候,也会进行“交换”,其实当左右指针都是非0,两个指针是相等的,自己交换自己,不影响结果,多余的操作而已。
- 当出现第一个0的时候,左右指针才会不相等。此时左指针指向的是0,右指针找到非0数,两者交换。
- 循环这个过程到结尾。
- 思路更简洁了。但是对我来说,好像不能一下子想出来。
class Solution {public void moveZeroes(int[] nums) {int n = nums.length;int left = 0;for (int right = 0; right < n; right++) {if (nums[right] != 0) {// 交换 nums[right] 和 nums[left]int tmp = nums[right];nums[right] = nums[left];nums[left] = tmp;left++;}}}
}
11. 盛最多水的容器
思路:
class Solution {public int maxArea(int[] height) {int n = height.length;int left = 0;int right = n - 1;int res = Integer.MIN_VALUE;while (left < right) {// 面积=底边宽度*较小的高度int area = (right - left) * Math.min(height[left], height[right]);// 刷新最大值res = Math.max(res, area);// 那边值小移动哪一边,相等移动谁无所谓if (height[left] < height[right]) {left++;} else {right--;}}return res;}
}
15. 三数之和
思路【我】:
双指针法,其实也可以叫三指针法。因为i也算是一个指针了。
但因为左右指针是同一轮循环里面移动的,i算一层,left和right算一层,总共两层循环。
- 要对每个数进行去重。因为是排序过的,每次对比相邻的两个数就好。
class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res = new ArrayList<>();// 排序数组Arrays.sort(nums);for (int i = 0; i < nums.length; i++) {// 已经排序过了,如果nums[i]>0,后面的两个元素也会大于0,就无法相加为零,代表循环结束,可以直接返回。if (nums[i] > 0) {break;}// 去重aif (i > 0 && nums[i] == nums[i - 1]) {continue;}int left = i + 1;int right = nums.length - 1;while (left < right) {int sum = nums[i] + nums[left] + nums[right];// 当sum >0,证明数太大了,右指针左移。下同理if (sum > 0) {right--;} else if (sum < 0) {left++;} else if (sum == 0) {res.add(Arrays.asList(nums[i], nums[left], nums[right]));// 去重b和cwhile (left < right && nums[left] == nums[left + 1]) {left++;}while (left < right && nums[right] == nums[right - 1]) {right--;}left++;right--;}}}return res;}
}