Binary Search 中几道 Rotated sorted array题目的整理

总结放前面:

BS 找 Rotated sorted array 的题目目前接触到的共四道: 33, 81, 153, 154. 两道找find target, 两道find min. 其中各包含一道no duplicate 一道contain duplicates.

重点如下:

1. 主体思路:

  大框架与经典BS题目相同, find target 的题目用classic经典方法[while(left <= right)], find min用改版方法[while(left + 1 < right) + post process].

2. 针对Rotated做出的改变:

  因为是rotated sorted array, 所以多数情况 left<-->mid 和 mid<-->right 这两段中, 有一段是顺序的,一段不是. [if (nums[left] < nums[mid])]. (后面再讨论全顺序的情况)

  针对这种情况的处理方法是, 把不好判断的部分全部丢到else里面去!

  举例:

        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) return mid;
            else if (nums[mid] < nums[right]) {
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            } else {
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
        }

  LT33, rotated sorted array, find target, no duplicate.

  这段代码中, 将经典的classic方法做了加工, 在判断target和nums[left]/nums[right]之前多了一步[else if (num[mid] < nums[right])].

  通过这个来判断当前iter中, 哪半边儿是sorted, 哪半边儿不是.

  然后在sorted的那半边儿! 进行进一步判断[if (nums[left] <= target && target < nums[mid])]. 判断target在不在sorted的这半边儿中, 这一步相当于将新问题转化成我们熟悉的问题. 到这里有细心的小伙伴就要问了, target不在这个范围中该怎么办呢? 

  不要慌张!!

  对于out of our control的部分! 全部甩到else里就够了[奸笑]

  以上就是rotated sorted array的灵魂(soul~~~~)

  BTW, find min的那道题更简单, 连target都没有, 就套用这个思路洒洒水就出来了.

 

3. 针对duplicates做出的变化:

  对于duplicates的情况, 说穿了就是比no duplicate的情况多了两个判断:

    else if (nums[left] == nums[mid])  left++;

    else if (nums[mid == nums[right])  right--; <--

  就这么简简单单 (?只是简简单单的爱过, 我~还~是~我~)

4. 追加考虑rotated的情况中出现unrotated的情况(mmp……)

  LeetCode 154, 需要在最前面考虑nums[left] < nums[mid] < nums[right]的情况 (别问我为什么鬼知道…反正不加这一句就不accepted……)

5. Note:

  这类题应先判断mid<-->right这段, 然后把left<-->mid这段放在else中.

 

好了以上就是这四道题的所有思路, 下面是各道题的野原新之助ver 答案, 仅供参考.

 

LeetCode 33.

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

KEY WORDS:  [Rotated sorted array]  [find target]  [no duplicate]

    public int search(int[] nums, int target) {
        if (nums == null || nums.length == 0) return -1; 
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;
        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) return mid;
            else if (nums[mid] < nums[right]) {
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            } else {
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            }
        }
        return -1;
    }

 

 

LeetCode 81:

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Write a function to determine if a given target is in the array.

The array may contain duplicates.

KEY WORDS:  [Rotated sorted array]  [find target]  [contain duplicates]

    public boolean search(int[] nums, int target) {
        if (nums == null || nums.length == 0) return false;
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return true;
            } else if (nums[left] < nums[mid]) {
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            } else if (nums[mid] < nums[right]) {
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            } else if (nums[left] == nums[mid]){
                left++;
            } else {
                right--;
            }
        }
        return false;
    }

 

LeetCode 153:

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.

KEY WORDS:  [Rotated sorted array]  [find min]  [no duplicates]

    public int findMin(int[] nums) {
        if (nums == null || nums.length == 0) return -1;
        
        int left = 0;
        int right = nums.length - 1;
        
        while (left < right - 1) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < nums[right]) {
                right = mid;
            } else {
                left = mid;
            }
        }
        if (nums[left] < nums[right]) {
            return nums[left];
        } else {
            return nums[right];
        }
    }

 

LeetCode 154:

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

The array may contain duplicates.

KEY WORDS:  [Rotated sorted array]  [find min]  [contains duplicates]

    public int findMin(int[] nums) {
        if (nums == null || nums.length == 0) {
            return -1;
        }
        
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;
        
        while (left < right - 1) {
            mid = left + (right - left) / 2;
            if (nums[left] < nums[mid] && nums[mid] < nums[right]) {
                right = mid;
            } else if (nums[mid] == nums[right]) {
                right--;
            } else if (nums[left] == nums[mid] ) {
                left++;
            } else if (nums[left] < nums[mid]) {
                left = mid;
            } else {
                right = mid;
            }
        }
        
        if (nums[left] < nums[right]) {
            return nums[left];
        } else {
            return nums[right];
        }
    }

 

posted on 2018-03-25 04:40  野原新之助0 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/chrislyr/p/8642748.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值