LeetCode Notes_ # 81 search rotation sorted array II

LeetCode Notes_ # 81 search rotation sorted array II

Contents

topic

Suppose ascending order according to the array was rotated in a previously unknown point.

(E.g., array [0,0,1,2,2,5,6] may become [2,5,6,0,0,1,2]).

Write a function to determine whether a given target is present in the array. Returns true if there is, otherwise false.

Example 1:

输入: nums = [2,5,6,0,0,1,2], target = 0
输出: true
示例 2:
输入: nums = [2,5,6,0,0,1,2], target = 3
输出: false

Advanced:
This is an extension of the subject search rotation sorted array, this question is repeated nums may contain elements.
This will affect the time complexity of the program do? What will be the impact, and why?

Thinking

  • This problem only difference with 33 questions that allow duplicate numbers, so every time when the binary search, you can not judge ordered the midpoint of the left or right and orderly. If nums[start] == nums[mid], directly ignored start, since increased again to start ++ judgment.

思路图解
Graphic ideas

answer

  1. class Solution { 
  2. public boolean search(int[] nums, int target) { 
  3. int len = nums.length; 
  4. int start = 0; 
  5. int end = len - 1 ; 
  6. // ERROR: consider entering empty corner case 
  7. if (len == 0) return false; 
  8. //TIP:start,end相邻的时候,就已经可以结束了,防止再去计算mid,与start比较,会陷入死循环 
  9. while(start + 1 < end){ 
  10. //TIP:防止溢出,mid是负数 
  11. //如果数字比较大,用mid = (start + end) / 2的写法就可能会溢出 
  12. int mid = start + (end - start) / 2; 
  13. if (nums[mid] == target) return true; 
  14. if (nums[mid] == nums[start]) start++; 
  15. if (nums[mid] > nums[start]){ 
  16. //ERROR:这里不仅仅要和mid比大小,还要和start比大小 
  17. if (nums[mid] > target && nums[start] <= target) end = mid; 
  18. else start = mid; 
  19. //ERROR:这里不能直接写else,否则nums[mid]==nums[start]时,也会进入这里边,三个分支一定是互斥的 
  20. }else if(nums[mid] < nums[start]){ 
  21. //ERROR:这里不仅仅要和mid比大小,还要和end比大小 
  22. //为什么上边是和start比,这里是和end比? 
  23. //因为必须是在一个单调区间比较才有意义,这里已经确定了是在后一个单调区间,所以跟end比才有意义。start同理。 
  24. if(nums[mid] < target && nums[end] >= target) start = mid; 
  25. } 
  26. } 
  27. //TIP:由于在start和end相邻的时候已经终止循环了,所以循环结束后,要单独判定start/end 
  28. //假如start+1==end时,依然进行二分搜索,mid == start,这时就不知道target在左侧还是右侧,只能直接判断 
  29. if(nums[start] == target) return true; 
  30. if(nums[end] == target) return true;  
  31. //如果所有都执行完了,没有返回true,就是不在数组里边 
  32. return false; 
  33. } 
  34. } 

这里在注释当中以标签的形式写了一些内容,ERROR代表我犯过的错误,TIP是技巧的总结。我发现与其单独写一段话描述代码思路,不如直接写在注释里,复习的话,直接看代码就完事了,方便。

体会

写笔记的目的不是为了好看,而是为了自己整理思路和回顾,所以反而随意一点(反正也不会有人看...),才能坚持下来,以前想着要把这个题解写的多么好,但是现实就是我目前还很菜,先能自己大概写一写,能进入一个刷题的良性循环才是王道,如果非要追求每题都自己搞清楚,太费时间,可能某一段时间比较闲,可以坚持住,那要是没有时间,这个习惯就会被抛弃。总的来说,要循序渐进。

Guess you like

Origin www.cnblogs.com/Howfars/p/12001351.html