5.20 寻找第k个最小数
This commit is contained in:
parent
353b7c0267
commit
71799259b9
@ -1,7 +1,5 @@
|
||||
package array;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* 题目: 918. 环形子数组的最大和 (maxSubarraySumCircular)
|
||||
|
64
src/main/java/binary_search/FindMedianSortedArrays.java
Normal file
64
src/main/java/binary_search/FindMedianSortedArrays.java
Normal file
@ -0,0 +1,64 @@
|
||||
package binary_search;
|
||||
/**
|
||||
* 题目: 4. 寻找两个正序数组的中位数 (findMedianSortedArrays)
|
||||
* 描述:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
|
||||
*
|
||||
* 算法的时间复杂度应该为 O(log (m+n)) 。
|
||||
*
|
||||
示例 1:
|
||||
输入:nums1 = [1,3], nums2 = [2]
|
||||
输出:2.00000
|
||||
解释:合并数组 = [1,2,3] ,中位数 2
|
||||
*
|
||||
* 链接:https://leetcode.cn/problems/median-of-two-sorted-arrays/
|
||||
|
||||
*/
|
||||
//不会
|
||||
public class FindMedianSortedArrays {
|
||||
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
|
||||
int m = nums1.length, n = nums2.length;
|
||||
int total = m + n;
|
||||
if (total % 2 == 1) {
|
||||
// 奇数长度,直接取第 (total+1)/2 小
|
||||
return getKth(nums1, 0, nums2, 0, (total + 1) / 2);
|
||||
} else {
|
||||
// 偶数长度,取第 total/2 和 total/2+1 两个数的平均
|
||||
double left = getKth(nums1, 0, nums2, 0, total / 2);
|
||||
double right= getKth(nums1, 0, nums2, 0, total / 2 + 1);
|
||||
return (left + right) / 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
// 返回 nums1[start1...] 和 nums2[start2...] 中,第 k 小的数
|
||||
private double getKth(int[] nums1, int start1, int[] nums2, int start2, int k) {
|
||||
// 如果 nums1 已经“耗尽”,直接从 nums2 里取
|
||||
if (start1 >= nums1.length) {
|
||||
return nums2[start2 + k - 1];
|
||||
}
|
||||
// 如果 nums2 耗尽
|
||||
if (start2 >= nums2.length) {
|
||||
return nums1[start1 + k - 1];
|
||||
}
|
||||
// 如果 k == 1,取两数组当前头部较小者
|
||||
if (k == 1) {
|
||||
return Math.min(nums1[start1], nums2[start2]);
|
||||
}
|
||||
|
||||
// 各自看 k/2 位置的元素,如果超出边界,则视作 +∞
|
||||
int midVal1 = (start1 + k/2 - 1 < nums1.length)
|
||||
? nums1[start1 + k/2 - 1]
|
||||
: Integer.MAX_VALUE;
|
||||
int midVal2 = (start2 + k/2 - 1 < nums2.length)
|
||||
? nums2[start2 + k/2 - 1]
|
||||
: Integer.MAX_VALUE;
|
||||
|
||||
// 抛弃较小者及其前面 k/2 个元素
|
||||
if (midVal1 < midVal2) {
|
||||
// 抛弃 nums1[start1 ... start1 + k/2 - 1]
|
||||
return getKth(nums1, start1 + k/2, nums2, start2, k - k/2);
|
||||
} else {
|
||||
// 抛弃 nums2[start2 ... start2 + k/2 - 1]
|
||||
return getKth(nums1, start1, nums2, start2 + k/2, k - k/2);
|
||||
}
|
||||
}
|
||||
}
|
47
src/main/java/binary_search/FindPeakElement.java
Normal file
47
src/main/java/binary_search/FindPeakElement.java
Normal file
@ -0,0 +1,47 @@
|
||||
package binary_search;
|
||||
/**
|
||||
* 题目: 162. 寻找峰值 (findPeakElement)
|
||||
* 描述:峰值元素是指其值严格大于左右相邻值的元素。
|
||||
* 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
|
||||
* 你可以假设 nums[-1] = nums[n] = -∞ 。
|
||||
* 你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
|
||||
*
|
||||
示例 1:
|
||||
输入:nums = [1,2,3,1]
|
||||
输出:2
|
||||
解释:3 是峰值元素,你的函数应该返回其索引 2。
|
||||
*
|
||||
* 链接:https://leetcode.cn/problems/find-peak-element/
|
||||
|
||||
*/
|
||||
public class FindPeakElement {
|
||||
public int findPeakElement1(int[] nums) {
|
||||
int pre=Integer.MIN_VALUE;
|
||||
for (int i = 0; i < nums.length-1; i++) {
|
||||
int cur=nums[i];
|
||||
int next=nums[i+1];
|
||||
if(pre<cur&&cur>next)
|
||||
return i;
|
||||
pre=cur;
|
||||
}
|
||||
if(nums[nums.length-1]>pre)
|
||||
return nums.length-1;
|
||||
else return 0;
|
||||
}
|
||||
//二分查找 Ologn
|
||||
public int findPeakElement(int[] nums) {
|
||||
int l = 0, r = nums.length - 1;
|
||||
while (l < r) {
|
||||
int mid = l + (r - l) / 2;
|
||||
// 如果右侧更“高”,就在右半区继续寻找
|
||||
if (nums[mid] < nums[mid + 1]) {
|
||||
l = mid + 1;
|
||||
} else {
|
||||
// 否则峰值在左半区(包括 mid 自身)
|
||||
r = mid;
|
||||
}
|
||||
}
|
||||
// l == r,即为峰值下标
|
||||
return l;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user