关于java:Search-in-Rotated-Sorted-Array-循环有序数组查找问题

37次阅读

共计 1968 个字符,预计需要花费 5 分钟才能阅读完成。

两道题

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

}

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

正文完
 0