代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素、977.有序数组的平方
2026/9/15 13:17:15 网站建设 项目流程

704. 二分查找

文档讲解:

代码随想录

视频讲解:手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili

看到题目后第一想法:正常二分

看完代码随想录后的想法:居然有两个二分

题目总结:

//左闭右闭 class Solution { public int search(int[] nums, int target) { int l = 0,r = nums.length-1; while(l<=r){ int i = (l+r)/2; if(nums[i] == target) return i; if(nums[i] < target) l = i+1; else r = i-1; } return -1; } } //左闭右开 class Solution { public int search(int[] nums, int target) { int l = 0,r = nums.length-1; int s; while(l<r){ s = (r+l)/2; if(nums[s] == target) return s; if(nums[s] > target) r = s; else l = s+1; } return -1; } }

两个二分的区别就是区间的选取不同

为什么都是左闭?因为自动向下取整,所以左边一定是闭区间,右边则需要加上等于才算闭区间

当左闭右闭时包括中间元素,所以左右指针不包括中间元素

当左闭右开时不包括中间元素,所以右指针需要包括中间元素,而左指针因为向下取整天然包括,就不需要包括中间了

当选取左闭右闭区间时,循环判断条件为while (left <= right),目标在左区间时if (nums[middle] > target) right = middle - 1;

当选取左闭右开区间时,循环判断条件为while (left < right),目标在左区间时if (nums[middle] > target) right = middle;

若第一种:while (left <= right)且right = middle时[-1,0,3,5,9,12],target =2会使l = r = 2,都指向3,此时中间值大于2但r不变,无限循环下去

若第二种:为while (left < right)且right = middle-1;时若输入的数组为【5】target=5,则会返回-1

27. 移除元素

文档讲解:

代码随想录

视频讲解:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili

看到题目后第一想法:找到对应值,然后将后面元素前移

看完代码随想录后的想法:快慢指针和双指针

题目总结:

//我的 class Solution { public int removeElement(int[] nums, int val) { int l = 0,r = 0,len = nums.length; if(len == 0) return 0; while(l<len && r<len){ while(r<len && nums[r] == val){ r++; } if(r<len){ nums[l] = nums[r]; l++;r++; } } return l; } } //标准快慢指针 class Solution { public int removeElement(int[] nums, int val) { int slow = 0; // 慢指针:下一个存放有效元素的位置 // 快指针遍历整个数组 for (int fast = 0; fast < nums.length; fast++) { // 遇到不等于 val 的元素,就放到慢指针位置 if (nums[fast] != val) { nums[slow] = nums[fast]; slow++; } } return slow; } } //标准双向指针(适配元素可打乱情况) class Solution { public int removeElement(int[] nums, int val) { int left = 0, right = nums.length - 1; while (left <= right) { if (nums[left] == val) { nums[left] = nums[right]; right--; } else { left++; } } return left; } } //我的双向指针 class Solution { public int removeElement(int[] nums, int val) { int l = 0,r = nums.length-1; while(l<=r){ if(l == r){ if(nums[l] != val) return l+1; else return l ; } while(nums[l] != val && l<r) l++; while(nums[r] == val && r>l) r--; if(l<r) nums[l++] = nums[r--]; } return l; } }

快慢指针:设立快慢指针,遍历数组,刚开始都指向0,if快指针没遇到目标值,就将快指针位置的值赋予慢指针,否则快指针+1

双指针:一左一右两个指针,循环条件为左指针小于等于右指针,左指针找val,右指针找非val,找到后交换位置

自己的写法都是批量式处理的逻辑,这样的话会循环套循环,容易出错,标准写法都是每次循环只处理一件事,逻辑简单,代码量也少

977.有序数组的平方

文档讲解:

代码随想录

视频讲解:双指针法经典题目 | LeetCode:977.有序数组的平方_哔哩哔哩_bilibili

看到题目后第一想法:先平方,后排序

看完代码随想录后的想法:双指针

题目总结:

class Solution { public int[] sortedSquares(int[] nums) { int [] res = new int [nums.length]; int l = 0,r = nums.length-1; while(l<nums.length){ nums[l] = nums[l]*nums[l]; l++; } l = 0; int i = r; while(l<=r){ if(nums[l]>nums[r]) res[i--] = nums[l++]; else res[i--] = nums[r--]; } return res; } }

双指针:先设立一个新数组(装最后的返回值),在原来的数组中先都平方,然后最大值肯定在两端,此时,设立双指针,一左一右,进入循环,条件为左小于等于右,找最大值,放入新数组末尾,然后向中心移动指针。

鉴于作者水平有限,文章可能存在错误

如有指正,十分感谢

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询