算法练习 | LeetCode704二分查找、LeetCode27移除元素

96 阅读3分钟

LeetCode704二分查找

题目描述:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

题目链接:leetcode.cn/problems/bi…

解题思路

  • 这道题其实重点在于对二分法的要点掌握,二分法通过取中间值来进行比较,但是解题思路重点应该放在不断分割的区间,而不是中间值。
  • 要理解区间的含义,区间代表当前数组所要进行查询的范围,通常是左闭右闭、左闭右开两种。
  • 写的时候要时刻注意保持上下区间格式一致。

解题方法及注意事项

方法一 | 左闭右闭

   let start = 0;
   let end = nums.length - 1;
   while(start <= end){
       let mid = Math.floor((start + end) / 2);
       console.log(start,end,mid)
       if(nums[mid] > target){
           end = mid - 1;
       } else if(nums[mid] < target){
           start = mid + 1;
       } else {
           return mid;
       }
   }
   return -1;

注意点

  1. 左闭右闭则代表该区间的两端都是要进行查找的数据,因此end的初始值在这应该是nums.length - 1
  2. while循环判断语句中,要用<=,因为对于左闭右闭区间来说,[x,x]是合法的区间存在。
  3. 在if判断中,如果中间值大于目标值,end应更改为mid - 1,原因是mid在此时已经和target进行了比较,因此再下一轮比较中不再需要查找,同理start的变化应为mid + 1
  4. 对于mid的取值,此处如果是(start + end)/2则会有浮点数出现,因此采用了Math.floor方法进行向下取整。

方法二 | 左闭右开

    let start = 0;
    let end = nums.length;
    while(start < end){
        let mid = Math.floor((start + end) / 2);
        if(nums[mid] > target){
            end = mid;
        } else if(nums[mid] < target) {
            start = mid + 1;
        } else{
            return mid;
        }
    }
    return -1;

注意点

  1. 在写完方法一后写这种方法时非常容易出错的地方在对end初始值的设置,此处的end是开区间,因此是不包括在内的,因此应该为nums.length
  2. 循环判断以及start、end的写法思路与方法一一致。

总结

在写这道题的时候,我知道是要用二分法,但是思路理所当然的将重点放在了中间值上,如果以中间值作为更改查找的切入点,那么解题过程会变得非常繁杂,需要考虑的特殊情况非常多。在经历了错误思路的折磨后,再看题解和视频豁然开朗,找到了思路的正确走向以及注意事项,因为在思路正确之后,解题时还是会在某些细节上出问题。

LeetCode27移除元素

题目描述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

题目链接:leetcode.cn/problems/re…

解题思路

  • 这道题如果用暴力解法做需要两次嵌套for循环,因此想要降低这道题的时间复杂度则最好使用双指针法。
  • 这道题的双指针分别为快慢指针,但解题思路的难点在于没有完全理解快慢指针所代表的含义。快指针用于对整个数组进行遍历,并找出等于val的数据;而慢指针则可以看作是一个新数组,接收的数据是原数组中不等于val的所有数据。

解题方法及注意点

方法一 | 暴力循环法

方法二 | 快慢指针法

总结

这道题虽然知道要用双指针去做,但是因为没能理解快慢指针的真正含义而使解题逻辑非常不清晰,在看完讲解后理解了其含义再写这道题就简单很多。