From 46a6f2851c79de41d4089949e58a6376774cd37b Mon Sep 17 00:00:00 2001 From: humingk Date: Thu, 13 Jun 2024 22:36:16 +0800 Subject: [PATCH] add --- _posts/2019-03-18-alg-note.md | 115 +++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/_posts/2019-03-18-alg-note.md b/_posts/2019-03-18-alg-note.md index 3683fe6..4432f2d 100644 --- a/_posts/2019-03-18-alg-note.md +++ b/_posts/2019-03-18-alg-note.md @@ -891,8 +891,10 @@ class Solution { ![](https://raw.githubusercontent.com/humingk/resource/master/image/2019/sort_quick_partition1.png) -前后遍历双切分: +###### 前后遍历双切分(推荐): + https://leetcode.cn/problems/sort-an-array/ + ```java public int[] sortArray(int[] nums) { if (nums == null || nums.length <= 1) { @@ -936,7 +938,7 @@ https://leetcode.cn/problems/sort-an-array/ } ``` -**前后遍历三切分(推荐):** +###### **前后遍历三切分(推荐):** ```java public int[] sortArray(int[] nums) { @@ -6007,7 +6009,7 @@ PS: --- -#### 解法2 类快速排序 O(N) + O(1) +#### 解法2 类快速排序 O(NLogN) + O(1) 比第k个数字小的所有数字都在k的左边,比第k个数字大的都在k的右边 @@ -6074,6 +6076,61 @@ public class Solution { } } ``` +oj:https://leetcode.cn/problems/smallest-k-lcci/ +另一种写法 + +```java +class Solution { + public int[] smallestK(int[] arr, int k) { + quickSort(arr, 0, arr.length - 1, k); + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = arr[i]; + } + return result; + } + + private void quickSort(int[] arr, int min, int max, int k) { + if (min >= max) { + return; + } + // 拆分 + int target = arr[min]; + int start = min, end = max + 1; + while (true) { + while (start < max && arr[++start] < target) + ; + while (end > min && arr[--end] > target) + ; + if (start < end) { + exchange(arr, start, end); + } else { + break; + } + } + exchange(arr, min, end); + // end左边的都小,end右边的都大,直接返回左边即可 + if (end == k - 1) { + return; + } + // end左边的有小有大,继续拆分左边 + else if (end > k - 1) { + quickSort(arr, min, end - 1, k); + } + // end右边的有大有小,继续拆分右边 + else { + quickSort(arr, end + 1, max, k); + } + } + + private void exchange(int[] arr, int left, int right) { + int temp = arr[left]; + arr[left] = arr[right]; + arr[right] = temp; + } +} +``` + ------ @@ -6184,6 +6241,9 @@ class Solution { + + + --- ### 连续子数组的最大和 @@ -6350,6 +6410,55 @@ public class Solution { } ``` +oj:https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/ +也可以通过判断两个队列大小是否相等来平分 + +```java +class MedianFinder { + + private PriorityQueue maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1); + private PriorityQueue minHeap = new PriorityQueue<>(); + + /** initialize your data structure here. */ + public MedianFinder() { + + } + + public void addNum(int num) { + // 平分插入堆 + if(minHeap.size()==maxHeap.size()){ + maxHeap.add(num); + // 最大堆的最大值插入最小堆 + minHeap.add(maxHeap.poll()); + }else{ + minHeap.add(num); + // 最小堆的最小值插入最大堆 + maxHeap.add(minHeap.poll()); + } + } + + public double findMedian() { + // 最小堆和最大堆个数一样,返回平均值 + if(minHeap.size()==maxHeap.size()){ + return (minHeap.peek()+maxHeap.peek())/(double)2; + } + // 最小堆和最大堆个数不一样,返回中位数 + else if(minHeap.size()>maxHeap.size()){ + return minHeap.peek(); + }else{ + return maxHeap.peek(); + } + } +} + +/** + * Your MedianFinder object will be instantiated and called as such: + * MedianFinder obj = new MedianFinder(); + * obj.addNum(num); + * double param_2 = obj.findMedian(); + */ +``` + ------ ### 整数中1出现的次数