前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >33. Search in Rotated Sorted Array

33. Search in Rotated Sorted Array

作者头像
翎野君
发布2023-05-12 20:26:31
1290
发布2023-05-12 20:26:31
举报
文章被收录于专栏:翎野君翎野君

两道题 

33. Search in Rotated Sorted Array

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

81. Search in Rotated Sorted Array II

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

这两道题都是属于循环有序数组的查找问题,无论是查找具体元素的下标还是检查一个目标值是否在数组中,主要的判断逻辑都是一致的。

思路

这种将有序数组翻转成循环有序数组的解决办法是将原数组分段。用首元素start、中间元素mid、尾元素end,可以将数组分为两个子数组s1,s2。

则这两个子数组中,必然有至少一个子数组是有序的。

那么如何确定那一段是有序的呢,通过分析可以看到只有3种情况:

  1. 当start就是A中最小的元素时,以下不等式成立:start <= mid <= end
  2. 当最小值位于(start, mid]时,则有:mid <= end <= start
  3. 当最小值出现在(mid,end]时,则有:end <= start <= mid

所以通过start, mid, end的大小关系,就可以判断出s1和s2哪个是有序的。

通过比较要查找的目标target与start,mid,end的大小关系,就可以知道target位于哪个子数组。

若target位于有序的子数组,则用二分查找就可以了。否则,对无序的子数组重复刚才的过程就可以了。

代码

代码语言:javascript
复制
package com.lingyejun.dating.chap11.toutiao;

public class RotatedArrayQuery {


    /**
     * 33. Search in Rotated Sorted Array
     * 查找目标值下标
     *
     * @param nums
     * @param target
     * @return
     */
    public int searchTargetIndex(int[] nums, int target) {
        int start = 0;
        int end = nums.length - 1;

        while (start <= end) {

            // (start ... middle ... end)
            int mid = (start + end) / 2;

            if (nums[mid] == target) {
                return mid;
            }

            // 前半段数组是有序的
            if (nums[start] < nums[mid]) {
                // target在前半段数组中
                if (target < nums[mid] && target >= nums[start]) {
                    // 将原数组折半,取出前半段数组
                    end = mid - 1;
                } else {
                    // target在后半段数组中
                    start = mid + 1;
                }
            }

            // 后半段数组是有序的
            else if (nums[mid] < nums[end]) {
                // target在后半段数组中
                if (target > nums[mid] && target <= nums[end]) {
                    // 将原数组折半,取出后半段数组
                    start = mid + 1;
                } else {
                    // target在前半段数组中
                    end = mid - 1;
                }
            } else {
                // 此种场景{1, 0, 1, 1, 1} start = mid = end
                start++;
            }
        }
        return -1;
    }

    /**
     * 81. Search in Rotated Sorted Array II
     *
     * 查找是否存在目标值
     *
     * @param nums
     * @param target
     * @return
     */
    public static boolean searchExistsKey(int nums[], int target) {
        int start = 0;
        int end = nums.length - 1;

        while (start <= end) {

            int mid = (start + end) / 2;

            if (nums[mid] == target) {
                return true;
            }

            if (nums[start] < nums[mid]) {

                if (nums[start] <= target && target < nums[mid]) {
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            } else if (nums[start] > nums[mid]) {
                if (nums[mid] < target && target <= nums[end]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }

            } else {
                start++;
            }
        }
        return false;
    }

    public static void main(String[] args) {

        int[] array = new int[]{1, 0, 1, 1, 1};

        RotatedArrayQuery caq = new RotatedArrayQuery();

        System.out.println(caq.searchTargetIndex(array, 0));
        System.out.println(caq.searchExistsKey(array, 1));
    }

}

首发链接:https://cloud.tencent.com/developer/article/2285728

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 两道题 
    • 33. Search in Rotated Sorted Array
      • 81. Search in Rotated Sorted Array II
      • 思路
      • 代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档