两道题

  1. Search in Rotated Sorted Array

https://leetcode.com/problems...

  1. Search in Rotated Sorted Array II

https://leetcode.com/problems...

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

思路

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

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

那么如何确定那一段是有序的呢,通过剖析能够看到只有3种状况:

当start就是A中最小的元素时,以下不等式成立:start <= mid <= end

当最小值位于(start, mid]时,则有:mid <= end <= start

当最小值呈现在(mid,end]时,则有:end <= start <= mid

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

通过比拟要查找的指标target与start,mid,end的大小关系,就能够晓得target位于哪个子数组。

若target位于有序的子数组,则用二分查找就能够了。否则,对无序的子数组反复方才的过程就能够了。

代码

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));    }}

本篇文章如有帮忙到您,请给「翎野君」点个赞,感谢您的反对。