青海省建设厅备案网站,乐清网站设计哪家好,免费wordpress托管服务商,成全高清免费观看mv这题的本质还是二分搜索#xff0c;只是先用哪一半有序来锁定一个可信的有序区间#xff0c;然后在这个区间里用普通二分的逻辑排除另一半。整套思路同时适用于普通升序数组和旋转升序数组#xff0c;可以当成一个更通用的二分模板来记。algo1
题目与现象只是先用哪一半有序来锁定一个可信的有序区间然后在这个区间里用普通二分的逻辑排除另一半。整套思路同时适用于普通升序数组和旋转升序数组可以当成一个更通用的二分模板来记。algo1题目与现象为什么整体不升序还能二分题目给的是一个原本严格升序的数组整体向左旋转了一段比如原数组[0,1,2,4,5,6,7]旋转后[4,5,6,7,0,1,2]。旋转之后有两条重要性质notes.suhaib1数组被切成前后两段各自升序的形状只在某一个位置出现从大跳到小的转折点。不管在数组哪里取一个 mid把当前区间 [left, right] 切成两半总有一半是完全升序的连续区间。这就是整个解法的支点虽然整体不升序但每一步里总有一半是升序的在这半边上就可以像普通二分那样思考。algo1关键洞见如何判断哪一半有序假设当前在区间 [left, right] 上二分取中点 mid。想判断左半 [left, mid] 是否有序notes.suhaib1如果左半里存在旋转点即存在那次从大跳小的地方那么一定有nums[left] nums[mid]直觉上left 还在尾部大段mid 已经绕到头部小段所以左端值比中点值大。反过来说如果观测到nums[left] nums[mid]就说明在 [left, mid] 这一段里没有那次从大跳小也就没有旋转点这整段只能是原数组中的某一段连续片段因此是严格升序的。结论就是那句经典判定stackoverflow2若nums[left] nums[mid]左半 [left, mid] 有序否则右半 [mid, right] 有序因为整个结构最多只有一个转折点且两边至少有一边是连续升序。这一条就是改造版二分的额外成本而在普通有序数组里这个判定永远是左、右两边都升序于是是冗余信息。用有序的一半排除另一半不用管跳跃点一旦知道哪一半是连续升序就可以像普通二分一样做区间判断algo1如果左半有序nums[left] nums[mid]如果nums[left] target nums[mid]说明 target 一定在左半 [left, mid-1]于是收缩右端right mid - 1否则target 不可能在这段升序区间里只能在右半收缩左端left mid 1。如果右半有序nums[mid] nums[right]如果nums[mid] target nums[right]说明 target 一定在右半 [mid1, right]于是left mid 1否则target 只能在左半right mid - 1。整个过程中完全不需要显式找跳跃点designgurus1若跳跃点在被丢掉的那一半里直接连同那一半一起被扔掉若跳跃点在保留下来的这一半里下一轮再继续哪边有序 用有序边排除另一边区间会越来越小直到跳跃点的存在不再影响哪边有序的判断。可以把跳跃点当成一个被动角色它只是跟着被划分的区间一起被缩小或丢弃从头到尾都不需要专门处理。和普通二分有什么本质区别从决策依据的角度看两者的核心差异是geeksforgeeks2普通二分整体升序强前提对任意 mid左侧所有元素 nums[mid]右侧所有元素 nums[mid]。决策只要看target nums[mid]⇒ 去左边target nums[mid]⇒ 去右边。不需要看 nums[left] / nums[right]因为整体单调已经隐含左边都小右边都大。旋转数组上的二分整体不单调左半和右半都可能混有大值和小值。若只看 target vs nums[mid]会有很多例子把真正答案那半边排除掉。因此必须先做一步用 nums[left] / nums[mid] / nums[right] 判断哪一半是**当前这一步中仍然是连续升序的那一边**然后只在这半边里用普通二分的区间逻辑判断 target 在不在这段从而决定缩小到哪一边。airtribe1于是你可以把本题常用写法视为一个更通用的二分模板“先定位有序半边”——保证要用它做判断的一整段是单调升序的。“再在这段里用普通二分逻辑排除另一半”。在普通升序数组上这套模板也成立只是哪边有序的判断永远得出两边都有序于是那部分变成冗余在旋转数组上则是必需的。notes.suhaib1官方推荐方案与替代方案LeetCode 官方题解以及主流教程推荐的就是上面这套一次改造版二分在一个 while 循环里完成判断哪边有序 区间排除时间复杂度 O(logn)空间 O(1)。leetcode2另一个等价的经典方案是先找旋转点再做普通二分geeksforgeeks1先用二分找到最小值下标旋转点把数组逻辑上分成两段升序。再根据 target 与 nums[0] 的大小决定在前段还是后段上做普通二分。这两种方法复杂度一样本质上利用的是同一个性质升序数组经过一次整体旋转后依然有一半是连续升序可以当作普通有序区间来二分。algo1如果你想写一篇自己的博客可以直接用这四个板块组织结构旋转数组的形状与唯一一次掉下去的性质为何 nums[left] nums[mid] ⇒ 左半有序在有序半边上如何像普通二分一样排除另一半这套逻辑如何同时覆盖普通二分和旋转二分成为一个通用模板。