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

简介: Search in Rotated Sorted Array - 循环有序数组查找问题

两道题

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位于有序的子数组,则用二分查找就可以了。否则,对无序的子数组重复刚才的过程就可以了。

代码

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
0
0
0
12
分享
相关文章
多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!array.flat()用法与array.flatMap() 用法及二者差异详解
理论上array.flat()能做的事情,array.flatMap()都可以做,但是array.flat()更简单,占用内存更少,执行更快。 这个相对冷门一些,w3school上都没有相关教程,看到就是赚到,收藏就是财富! 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助
别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
这类问题的重点在于能不能突破基础思路,突破基础思路是从程序员入门变成中级甚至高级的第一步,如果所有需求都通过最基础的业务逻辑来做,是得不到成长的。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Array.forEach实战详解:简化循环与增强代码可读性;Array.forEach怎么用;面对大量数据时怎么提高Array.forEach的性能
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Leetcode Find Minimum in Rotated Sorted Array 题解
对一个有序数组翻转, 就是随机取前K个数,移动到数组的后面,然后让你找出最小的那个数,注意,K有可能是0,也就是没有翻转。
76 0
LeetCode 167 Two Sum II - Input array is sorted(输入已排序数组,求其中两个数的和等于给定的数)
给定一个有序数组和一个目标值 找出数组中两个成员,两者之和为目标值,并顺序输出
102 0
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
Java 中数组Array和列表List的转换
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章

  • 1
    JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
    41
  • 2
    通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据和性能优化,reduce()的使用详解(附实际应用代码)
    24
  • 3
    JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
    25
  • 4
    别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
    7
  • 5
    深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
    4
  • 6
    通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
    4
  • 7
    JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
    8
  • 8
    多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!array.flat()用法与array.flatMap() 用法及二者差异详解
    5
  • 9
    通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
    7
  • 10
    Array.forEach实战详解:简化循环与增强代码可读性;Array.forEach怎么用;面对大量数据时怎么提高Array.forEach的性能
    3
  • 1
    Java 中数组Array和列表List的转换
    15
  • 2
    JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
    51
  • 3
    通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式、聚合统计、处理树结构数据和性能优化,reduce()的使用详解(附实际应用代码)
    56
  • 4
    通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
    24
  • 5
    通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
    20
  • 6
    多维数组操作,不要再用遍历循环foreach了!来试试数组展平的小妙招!array.flat()用法与array.flatMap() 用法及二者差异详解
    20
  • 7
    别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
    37
  • 8
    Array.forEach实战详解:简化循环与增强代码可读性;Array.forEach怎么用;面对大量数据时怎么提高Array.forEach的性能
    14
  • 9
    深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
    33
  • 10
    JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
    67