fucking-algorithm icon indicating copy to clipboard operation
fucking-algorithm copied to clipboard

我写了首诗,把二分搜索算法变成了默写题 :: labuladong的算法小抄

Open utterances-bot opened this issue 3 years ago • 70 comments

文章链接点这里:我写了首诗,把二分搜索算法变成了默写题

评论礼仪 见这里,违者直接拉黑。

utterances-bot avatar Sep 06 '21 04:09 utterances-bot

自己验证了下34题,不能直接套用,有些case没有过,期望修复

Calmlzw avatar Sep 09 '21 14:09 Calmlzw

@Calmlzw @theSavageseens 说具体一些?我试了下可以通过的。

labuladong avatar Sep 10 '21 05:09 labuladong

试了34题,python是没问题的(下面答案里有个大哥建议直接用.index()笑死)

ThomasQY avatar Sep 24 '21 02:09 ThomasQY

试了34题,Java是没问题的

yuchengkang avatar Nov 22 '21 04:11 yuchengkang

C++也通过了,上面出错的同学,应该是没有注意循环后的细节吧?(比如我就是左边界忘记检查等于数组大小的时候了😥)

wyzjb123 avatar Nov 24 '21 07:11 wyzjb123

RuiMM avatar Nov 26 '21 08:11 RuiMM

妙呀

feymanpaper avatar Nov 28 '21 04:11 feymanpaper

双闭区间是精髓

alannesta avatar Nov 30 '21 22:11 alannesta

寻找左侧边界的⼆分搜索中 // target 比所有数都大 if (left == nums.length) return -1; 不是应该返回nums.length嘛?

bbfxier avatar Dec 04 '21 12:12 bbfxier

能否也讲解一下,如果数组里面不含有查找元素,那么如果找最左和最右,返回的值是否可以保证是数组里第一个比target大或者小的数?

PsycoTodd avatar Dec 06 '21 17:12 PsycoTodd

C,34题没问题(双闭区间)

tn233 avatar Dec 10 '21 07:12 tn233

自己验证了下34题,不能直接套用,有些case没有过,期望修复

不好意思,又重新验证了下,是正确的,之前应该是自己哪里弄错了,麻烦把这个issue删了吧,总是有推送邮件

admn410 avatar Dec 11 '21 01:12 admn410

一开始就判断 target 是否存在,最后就不用考虑越界的事了。

if (target < nums[left] || target > nums[right]) {
    return -1;
}

yfmei avatar Dec 28 '21 12:12 yfmei

请问大家我这样判断空数组为什么了leetcode不给过啊 if(nums.size() == 0) { return {-1, -1}; } leetcode一直显示runtime error

JiachengZhao98 avatar Jan 06 '22 06:01 JiachengZhao98

@JiachengZhao98 数组求长度,用这个:nums.length

z-ak-z avatar Jan 07 '22 07:01 z-ak-z

while(left < right) 的终止条件是 left == right,写成区间的形式就是 [right, right] 这句话的区间写错了吧应该是[right,right)

scs-0432 avatar Jan 24 '22 13:01 scs-0432

js 版,需要加一个 Math.floor

function binarySearch(nums, target) {
  let left = 0,
    right = nums.length - 1;
  while (left <= right) {
    const mid = Math.floor(left + (right - left) / 2);
    if (nums[mid] == target) {
      // 直接返回
      return mid;
    }
    if (nums[mid] < target) {
      left = mid + 1;
    } else if (nums[mid] > target) {
      right = mid - 1;
    }
  }
  // 直接返回
  return -1;
}

function leftBoundSearch(nums, target) {
  if (nums.length == 0) return -1;
  let left = 0;
  let right = nums.length - 1; // 注意

  while (left <= right) {
    const mid = Math.floor(left + (right - left) / 2);
    if (nums[mid] === target) {
      right = mid - 1; // 注意
    } else if (nums[mid] < target) {
      left = mid + 1; // 注意
    } else {
      right = mid - 1; // 注意
    }
  }
  // target 比所有数都大
  if (left >= nums.length) return -1;
  // 类似之前算法的处理方式
  return nums[left] === target ? left : -1;
}

function rightBoundSearch(nums, target) {
  if (nums.length == 0) return -1;
  let left = 0;
  let right = nums.length - 1; // 注意

  while (left <= right) {
    const mid = Math.floor(left + (right - left) / 2);
    if (nums[mid] === target) {
      left = mid + 1; // 注意
    } else if (nums[mid] < target) {
      left = mid + 1; // 注意
    } else {
      right = mid - 1; // 注意
    }
  }
  // target 比所有元素都小
  if (right < 0) return -1;
  // 类似之前算法的处理方式
  return nums[right] === target ? right : -1;
}

console.log(binarySearch([5, 8, 8, 8, 8, 10], 8));
console.log(leftBoundSearch([5, 8, 8, 8, 8, 10], 8));
console.log(rightBoundSearch([5, 8, 8, 8, 8, 10], 8));

jswxwxf avatar Feb 07 '22 05:02 jswxwxf

可以说是非常的赞了

Shellbye avatar Feb 09 '22 10:02 Shellbye

已经拿小本本记录了

deepbreath373 avatar Feb 10 '22 06:02 deepbreath373

寻找左侧边界的时候检查出界情况为什么要用 if (left >= nums.length) left越界最大不就是nums.length吗,难道left还有大于nums.length的情况?

csuwangwencong avatar Feb 15 '22 03:02 csuwangwencong

@csuwangwencong 这是一种编程习惯,就算可以只用 ==,但因为 >= 覆盖的区域要远大于 ==,所以更不容易出错。

labuladong avatar Feb 16 '22 02:02 labuladong

明白了,谢谢解答

csuwangwencong avatar Feb 17 '22 03:02 csuwangwencong

在找左侧边界的代码中,为何只考虑了left越界,没有考虑right也有可能越界。同理为何在右侧边界中只考虑了right越界,而没有考虑left越界

youthlql avatar Feb 23 '22 14:02 youthlql

比如说在寻找左侧边界中,target比最左边的数还小,那么rigth就会一直减小,直到<0越界,而代码中并没有考虑。

youthlql avatar Feb 23 '22 14:02 youthlql

nums[left] != target虽然说这个代码已经把这种情况考虑进去了,但个人觉得还是讲一下比较完整

youthlql avatar Feb 23 '22 15:02 youthlql

@youthlql 其实我也有同样的疑问

yej2021 avatar Feb 24 '22 23:02 yej2021

youthlql commented a day ago 在找左侧边界的代码中,为何只考虑了left越界,没有考虑right也有可能越界。同理为何在右侧边界中只考虑了right越界,而没有考虑left越界 youthlql commented a day ago 比如说在寻找左侧边界中,target比最左边的数还小,那么rigth就会一直减小,直到<0越界,而代码中并没有考虑。 @labuladong 这个能讲下吗?

yej2021 avatar Feb 25 '22 00:02 yej2021

@yej2021 你举个反例出来

labuladong avatar Feb 25 '22 06:02 labuladong

youthlql commented a day ago 在找左侧边界的代码中,为何只考虑了left越界,没有考虑right也有可能越界。同理为何在右侧边界中只考虑了right越界,而没有考虑left越界 youthlql commented a day ago 比如说在寻找左侧边界中,target比最左边的数还小,那么rigth就会一直减小,直到<0越界,而代码中并没有考虑。 @labuladong 这个能讲下吗?

image 这个代码考虑了,但是文章里面没细说

youthlql avatar Feb 25 '22 06:02 youthlql

在找左侧边界的代码中,为何只考虑了left越界,没有考虑right也有可能越界。同理为何在右侧边界中只考虑了right越界,而没有考虑left越界

假设Right 一直在往Left逼近,最极端情况就是Left一直保持初始值为0不变,Right逼近到最后就等于了Left,然后退出循环,这种情况下Right也不过等于0,不会越界。

jzk avatar Mar 02 '22 06:03 jzk