Leetcode: Search in Rotated Sorted Array & II

URL

https://leetcode.com/problems/search-in-rotated-sorted-array/#/description

描述

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.

解题思路

解题思路基本就是二分查找算法。不同之处在于普通情况下数组的数据的值是单调递增或者递减的,但是本题数组是经过旋转处理过的。可以这样理解,把之前的一个单调递增的数组分解成两个,每一个也都是单调递增。我们把前段单调递增的数组简称(前段),后段单调递增的数组简称(后段),前段第一个数值一定是大于后段最后一个数值。基于这样的性质,我们对二分查找算法进行改编。步骤如下:
1. 我们首先还是会获得中间位置的数组下标:mid = (start+end)/2;
2. 如果mid 位置上的值就是等于target,也就是我们查询的目标,则直接返回即可,程序终止;
3. 如果与target不相等,我们就要做一个额外的操作——判断mid在什么位置上,或者说mid的位置是出现在“前段”还是“后段”。判断的依据也很简单:nums[mid]是否大于nums[end],若大于则mid出现在前段,否则出现在后段。
4. 缩小start和end的位置,具体判断依据就放在下面的代码里,逻辑也很简单。

代码示例

public int search(int[] nums, int target) {
        int start = 0;
        int end = nums.length-1;
        while(start<=end){
            int mid = (start+end)/2;
            int key = nums[mid];
            if(key==target) return mid;
            if(key>nums[end]){//mid 出现在前段
                    if(target<key&&target>=nums[start]){
                        end=mid-1;
                    }else{
                        start=mid+1;
                    }
            }else {//mid出现在后段
                    if(target>key&&target<=nums[end]){
                        start=mid+1;
                    }else{
                        end=mid-1;
                    }
            }
        }
        return -1;
    }

Search in Rotated Sorted Array II

url:

https://leetcode.com/problems/search-in-rotated-sorted-array-ii/#/description

描述:

Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

解题思路

因为存在相同的元素,所以在判断mid出现哪个阶段的时候会出现一个问题——当nums[mid]==nums[end]的时候,你无法判断mid在前段还是后段,所以对于这种情况我们干脆不进行判断了,而是简单的将end的位置减小一个。这样做的结果是原来我是判断[start,end]这部分数组中是否出现target元素,现在我判断[start,end-1]部分。这样并不会带来数据的丢失,因为至少有nums[mid]的数值是与nums[end]相同的。基于这样的思路给出代码就很方便了。

代码示例

 private boolean searchHelper(int start,int end,int[]nums,int target){
        while(start<=end){
            int mid = (start+end)/2;
            int key = nums[mid];
            if(key==target) return true;
            if(key>nums[end]){
                if(target<key&&target>=nums[start]){
                    end=mid-1;
                }else{
                    start=mid+1;
                }
            }else if(key<nums[end]){
                    if(target>key&&target<=nums[end]){
                        start=mid+1;
                    }else{
                        end=mid-1;
                    }
            }else{
                end--;
            }
        }
        return false;
}

public boolean search(int[] nums, int target) {
        return searchHelper(0,nums.length-1,nums,target);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值