leetcode -- Find Minimum in Rotated Sorted Array II -- 重点,自己思路不清晰
2015-12-10 15:53
459 查看
https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/
知道怎么做,但是思路不清晰,不知道index的停止条件。
note: 只要nums[s] < nums[e] 那么肯定没有rotation。
参考: 结合Find Minimum in Rotated Sorted Array题目一起看
http://bookshadow.com/weblog/2014/11/06/find-minimum-in-rotated-sorted-array-ii/
http://bookshadow.com/weblog/2014/10/16/leetcode-find-minimum-rotated-sorted-array/
/article/4981669.html
/article/4981668.html
http://blog.csdn.net/myself9711/article/details/40426553
http://yucoding.blogspot.hk/2014/10/leetcode-question-find-minimum-in_27.html
但是这里不一样,如果nums[mid] == nums[high]就不知道最小值是在[low:mid]还是在[mid+1:high]中了。例如{3,3,1,3}, low应该等于 mid + 1, 而{1,3,3,3}中的high就应该等于mid - 1.所以这里的BS要把等号的情况单独拿出来。
这里首先不考虑[s,e]范围内递增的情况,即nums[e]>nums[s],否则直接跳出循环nums[s]即为最小值。另一点就是如果nums[mid] > nums[e] (注意这里没有等于), 注意这里这里mid只可能发生在左边部分,要不在重复值出现的位置,要不就在上升段,那么最小值肯定不会出现在mid这个位置,至多也就是mid + 1, 所以这里可以令s = mid + 1. 如果nums[mid] < nums[e], 注意没有等于,那么mid肯定出现在右边部分,这里不同的一点就是mid可能对应最后的最小值,所以这里可以令e = mid. 如果nums[mid] = nums[e], mid肯定出现在重复区域,这里可以理解为最小值肯定不在s上,所以s可以往前走一步。
再一次强调这里的推断都是在nums[e] <=nums[s]的条件下进行的。
知道怎么做,但是思路不清晰,不知道index的停止条件。
note: 只要nums[s] < nums[e] 那么肯定没有rotation。
参考: 结合Find Minimum in Rotated Sorted Array题目一起看
http://bookshadow.com/weblog/2014/11/06/find-minimum-in-rotated-sorted-array-ii/
http://bookshadow.com/weblog/2014/10/16/leetcode-find-minimum-rotated-sorted-array/
/article/4981669.html
/article/4981668.html
http://blog.csdn.net/myself9711/article/details/40426553
http://yucoding.blogspot.hk/2014/10/leetcode-question-find-minimum-in_27.html
理解
在没有重复值的时候,我们可以nums[mid]只有在low == high, 只有一个元素的情况下等于nums[high], 所以这个时候马上就要跳出while low<=high循环了,所以这个时候把等号放在nums[mid] <=nums[high]或者nums[mid] >=nums[high]都是可以的。但是这里不一样,如果nums[mid] == nums[high]就不知道最小值是在[low:mid]还是在[mid+1:high]中了。例如{3,3,1,3}, low应该等于 mid + 1, 而{1,3,3,3}中的high就应该等于mid - 1.所以这里的BS要把等号的情况单独拿出来。
方法1 含递归
class Solution: # @param num, a list of integer # @return an integer def findMin(self, num): ans = num[0] size = len(num) low, high = 0, size - 1 while low <= high: mid = (low + high) / 2 ans = min(ans, num[mid]) if num[mid] < num[high]: #min位于上升沿左侧 high = mid - 1 elif num[mid] > num[high]: #min位于左侧上升沿与右侧上升沿之间 low = mid + 1 else: #num[mid] == num[high]的情况下,不知道最小值是在左边还是右边,所以这里直接左右都递归 if low < mid:#这里只有一种情况low == mid, 即搜索范围只有两个或者一个元素,所以这个时候已经用ans = min(ans, num[mid])进行了判断,所以就不用进行这个递归了。这个条件不能去掉?why?再思考 ans = min(ans, self.findMin( num[low : mid + 1] )) if mid + 1 < high:这里也一样,只有在搜索范围只有两个或者一个元素的是,mid + 1>=high,所以不需要搜索。这个条件不能去掉?why?再思考 ans = min(ans, self.findMin( num[mid + 1 : high + 1] )) break#注意这里一定要有break return ans
方法2 返回nums[low],让low指向最小值
这里code中用s表示low,e表示high这里首先不考虑[s,e]范围内递增的情况,即nums[e]>nums[s],否则直接跳出循环nums[s]即为最小值。另一点就是如果nums[mid] > nums[e] (注意这里没有等于), 注意这里这里mid只可能发生在左边部分,要不在重复值出现的位置,要不就在上升段,那么最小值肯定不会出现在mid这个位置,至多也就是mid + 1, 所以这里可以令s = mid + 1. 如果nums[mid] < nums[e], 注意没有等于,那么mid肯定出现在右边部分,这里不同的一点就是mid可能对应最后的最小值,所以这里可以令e = mid. 如果nums[mid] = nums[e], mid肯定出现在重复区域,这里可以理解为最小值肯定不在s上,所以s可以往前走一步。
再一次强调这里的推断都是在nums[e] <=nums[s]的条件下进行的。
class Solution(object): def findMin(self, nums): """ :type nums: List[int] :rtype: int """ s, e = 0, len(nums) - 1 while s < e and nums[s] >= nums[e]:# when rotations。这里不能变成s<=e, 因为在{1}一个元素的情况下,s会越界,使得return nums[s]没有意义。 mid = (s + e)/2 if nums[mid] > nums[e]: s = mid + 1 elif nums[mid] < nums[e]:#如果mid刚好就是min的时候 e = mid else: s += 1## right shift the "left" to narrow the range, which can avoid redundant element.这里不知道最小值是在左边还是右边,所以反正最后也是返回nums[s],所以s前进是可以缩小范围的,一直到[s:e]是个递增区间就找到最小值nums[s]了 return nums[s]
思路3,效率最高,自己重写过
返回一个min ans就行。分三种情况nums[mid] > nums[high], nums[mid] < nums[high], nums[mid] == nums[high] (这里等于的时候,要去掉重复值,一般来说要用一个while来去掉,但是这里外面已经有一个while了,所以这里直接将high-=1就行了。自己可以举例)class Solution(object): def findMin(self, nums): """ :type nums: List[int] :rtype: int """ low = 0 high = len(nums) - 1 ans = nums[low]#注意这里也可以用10000初始化。 while low <= high : mid = (low + high) / 2 ans = min(ans, nums[mid]) if nums[mid] > nums[high]: low = mid + 1 elif nums[mid] < nums[high]: high = mid - 1 else: #这里nums[mid]等于了nums[high], #并且nums[mid]已经判断过最小值了。 #就要将重复值去掉。通常这里要用一个while循环将重复值去掉。 #但是这里因为外面有一个while,所以直接这里high -= 1就行了。 high -= 1 return ans
相关文章推荐
- android四大组件
- Android status icon remove
- window7上爬虫框架Scrapy的安装 --错误分析lxml
- 构造方法 练习
- 判断、添加和删除WordPress置顶文章的相关PHP函数小结
- 关于GCD开发的一些事儿
- 如此简单的Scroller
- 蓝牙技术——数据传输
- 帮你彻底解决eclipse(myeclipse)中写struts.xml配置文件
- spring mvc整合json
- 在MyEclipse配置的WebLogic上发布的应用,修改了页面源码后,应用前台怎么刷新、清缓存都不显示修改效果
- Angular2入门(三)
- MyEclipse 15 集成SVN
- 悲观锁讲解
- Remove Duplicates from Sorted Array
- c语言之sizeof
- loadrunner录制上传文件,但是回放失败
- sharepoint content type publishing
- 如何使用 Zend Expressive 建立 NASA 图片库?
- Bonfire: Title Case a Sentence 句子中单词首字母大写