关于 m = l + (r - l + 1) / 2 的问题
波波老师,在程序中出现死循环是因为 r 和 l 相邻造成的。按照您的处理方式,只要是 r-l == 奇数的情况,m 的取值都会比之前大 1,这固然可以解决 r 和 l 相邻带来的问题,但是理解起来是不是会更费力一些?如果这么写 int mid = r-l == 1 ? l + (r - l + 1) / 2 : r 是不是会更好理解?这样就能清楚地知道 r 和 l 相邻时有需要注意的情况,不过比起您那样写确实少了几分优雅。
正在回答 回答被采纳积分+1
赞思考!
其实,按照你的思路,这样写就 ok:int mid = r - l == 1 ? r : l + (r - l) / 2;
这样一来,表示 l 和 r 不相邻的时候,取中值的方式还是普通的方式,但是一旦 l 和 r 相邻,取右侧的值,来处理死循环的问题。
课程后续,我会推荐 Leetcode 的探索,其中,给出了一个模板,是这样的:
int binarySearch(vector<int>& nums, int target){ if (nums.size() == 0) return -1; int left = 0, right = nums.size() - 1; while (left + 1 < right){ // Prevent (left + right) overflow int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid; } else { right = mid; } } // Post-processing: // End Condition: left + 1 == right if(nums[left] == target) return left; if(nums[right] == target) return right; return -1; }
注意,这个代码不是在求 lower,而是在做查找,但是我们可以用这个思路将其改造成 lower 或者 upper。
这个代码的关键是,while 的条件是 left + 1 < right,换句话说,在 left + 1 == right,即 left 和 right 相邻的时候,退出循环,之后,在循环外,分别对 left 和 left + 1(即 right)进行验证,使用这种方式来处理 left 和 right 相邻的时候可能出的问题。
我觉得这两个思路都是 ok 的,其实都是意识到了 left 和 right 相邻的时候可能出问题,对他们进行特殊处理。在这个思想基础上,他们代码的逻辑都是正确的,我认为你应该采取你觉得可读性最强的,最好理解的代码:)
不过,可读性强,易理解,并非是一个客观标准,每一个人的想法不一样,每一个团队的标准也不一样,在这种情况下,只要选择一个大家(或者自己)都能接受的写法就好了:)我的课程只是把我常用的一个方法呈现给大家:)
感谢你提供的思路。非常赞!继续加油!:)
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星