总结

1、一涉及到有序数组,就要想到用二分查找解决。关于二分查找主题:https://leetcode-cn.com/leetbook/read/binary-search/

1 一个有序数组

1.1 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。链接:https://leetcode-cn.com/problems/binary-search

1.1.1 返回任意一个

 

1.1.2 返回index最小

有时候有相同数,我们需要返回index最下的数,此时就是

 

1.2 找到 K 个最接近的元素 

给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-k-closest-elements

算法:

  • 二分查找时,两个数与 x 的差值一样,优先选择数值较小的那个数。
  • 二分找到position时,需要确定真正最小的位置
  • 计算差要取绝对值

1.3 在排序数组中查找元素的第一个和最后一个位置

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

你的算法时间复杂度必须是 O(log n) 级别。

如果数组中不存在目标值,返回 [-1, -1]。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array

 

方案1  先快排找到位置,再顺序找

算法:

  • 二分查找,实现查找一个元素,返回index最下的元素坐标
  • 需要在外层判断if(nums[position] != target)

 

方案2 通过两次快排完成

2 自旋数组

山脉数组是一条折线。自旋数组是平行线。

2.1 寻找自选数据的最小值 

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof

算法: 核心就是确定递归的beg和end

 

3两个有序数组

3.1 查找第K个数 

输入两个有序数组,查找第K个元素,比如:

输入:[1,2],[1,3],第2个

输出:2

算法如下:

  • 每次查询k/2个数。存在数组长度小于k/2的情况,所以需要每个数组的对应的k/2位置为:Math.min(len1, k / 2)。
  • 三个截止条件。

代码

3.2 中位数  

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。

链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0
示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

方法1 通过合并有序数组实现O(M+N)

1、思路

合并有序数组

2、算法

 

方法2 通过查找两个有序数组第K个数(O(Log(N+M)))

中位数分为两种情况

  • 如果是奇数,有序数组的(length1 + length2 – 1) / 2为中位数,相当于查找数组中第(length1 + length2 – 1) / 2 + 1 的数。
  • 如果是偶数,查找有序数组中(length1 + length2 – 2) / 2,(length1 + length2 ) / 2的数,相当于(length1 + length2 – 2) / 2  + 1 ,(length1 + length2 ) / 2  +1 

 

 

4  山脉数组(先升再降、先降再升)

4.1  查看最小值(同5.1.2 查询峰谷)

问题:一个先降序再升序的数组,寻找最小值。

输入:[8,4,2,3,7]

输出:2

算法:参考下节中 查看数组的峰谷

 

4.2 查找某一个值

问题:一个先降序再升序的数组,寻找k值。

输入:[8,4,2,3,7],查询7

输出:4

算法实现思路:

  • STEP1 首先定位拐点。参考上面查找4.1中查找足queyMin方法。
  • STEP2 分别对两个数组进行二分查找,看在那个数组中。

5 无序数组

5.1 查找峰值/峰谷 (二分)

5.1.1  查找峰值

峰值元素是指其值大于左右相邻值的元素。注意:峰值不是最大值。

给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。

数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-peak-element

算法思想:mid和右边比较,如果mid大,则向左找最大,可以认为mid右边比它小。

算法实现:

  • 为什么 mid和右边比较呢?mid = (beg + end) / 2;因为存在2个以及以上元素时,肯定存在mid+1,但是不一定存mid-1。
  • 在(nums[mid] > nums[mid + 1])情况下,search(nums, beg, mid )不是search(nums, beg, mid -1)

 

 

5.1.2 查找峰谷

算法,通过峰谷

 

分类&标签