From d28142efa199ead8ec2ca21e9b7bac264fe7788b Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Fri, 4 Apr 2025 12:05:49 +0800 Subject: [PATCH] =?UTF-8?q?4.4=20=E8=B4=AA=E5=BF=83=20=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/greedy/FindContentChildren.java | 34 +++++++++++ src/main/java/greedy/MaxProfit.java | 36 ++++++++++++ src/main/java/greedy/WiggleMaxLength.java | 45 +++++++++++++++ src/main/java/heap/FindKthLargest.java | 45 ++++++++++++++- src/main/java/heap/TopKFrequent.java | 40 +++++++++++++ src/main/java/sort/BubbleSort.java | 26 +++++++++ src/main/java/sort/MergeSort.java | 56 +++++++++++++++++++ src/main/java/sort/QuickSort.java | 46 +++++++++++++++ .../java/greedy/FindContentChildrenTest.java | 15 +++++ 9 files changed, 340 insertions(+), 3 deletions(-) create mode 100644 src/main/java/greedy/FindContentChildren.java create mode 100644 src/main/java/greedy/MaxProfit.java create mode 100644 src/main/java/greedy/WiggleMaxLength.java create mode 100644 src/main/java/heap/TopKFrequent.java create mode 100644 src/main/java/sort/BubbleSort.java create mode 100644 src/main/java/sort/MergeSort.java create mode 100644 src/main/java/sort/QuickSort.java create mode 100644 src/test/java/greedy/FindContentChildrenTest.java diff --git a/src/main/java/greedy/FindContentChildren.java b/src/main/java/greedy/FindContentChildren.java new file mode 100644 index 0000000..82f60c4 --- /dev/null +++ b/src/main/java/greedy/FindContentChildren.java @@ -0,0 +1,34 @@ +package greedy; + +import java.util.Arrays; + +/** + * 题目: 455. 分发饼干 (maxProfit) + * 描述:给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 + * 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 + * 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。 + + * 示例 1: + 输入: g = [1,2,3], s = [1,1] + 输出: 1 + 解释:你有三个孩子和两块小饼干,3 个孩子的胃口值分别是:1,2,3。 + 虽然你有两块小饼干,由于他们的尺寸都是 1,你只能让胃口值是 1 的孩子满足。 + 所以你应该输出 1。 + + * 链接:https://leetcode.cn/problems/assign-cookies/ + */ +public class FindContentChildren { + public int findContentChildren(int[] g, int[] s) { + int i=0,j=0,cnt=0; + Arrays.sort(g); + Arrays.sort(s); + while (i maxprofit) { + maxprofit = price - minprice; + } + } + return maxprofit; + } +} diff --git a/src/main/java/greedy/WiggleMaxLength.java b/src/main/java/greedy/WiggleMaxLength.java new file mode 100644 index 0000000..9e8641b --- /dev/null +++ b/src/main/java/greedy/WiggleMaxLength.java @@ -0,0 +1,45 @@ +package greedy; +/** + * 题目: 376. 摆动序列 (wiggleMaxLength) + * 描述:如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 + * 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。 + * 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 + * 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 + * 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。 + + * 示例 1: + 输入:nums = [1,7,4,9,2,5] + 输出:6 + 解释:整个序列均为摆动序列,各元素之间的差值为 (6, -3, 5, -7, 3) 。 + + 示例 2: + 输入:nums = [1,17,5,10,13,15,10,5,16,8] + 输出:7 + 解释:这个序列包含几个长度为 7 摆动序列。 + 其中一个是 [1, 17, 10, 13, 10, 16, 8] ,各元素之间的差值为 (16, -7, 3, -3, 6, -8) 。 + * 链接:https://leetcode.cn/problems/wiggle-subsequence/ + */ +//不会 https://programmercarl.com/0376.%E6%91%86%E5%8A%A8%E5%BA%8F%E5%88%97.html +public class WiggleMaxLength { + public int wiggleMaxLength(int[] nums) { + if (nums.length <= 1) { + return nums.length; + } + //当前差值 + int curDiff = 0; + //上一个差值 + int preDiff = 0; + int count = 1; + for (int i = 1; i < nums.length; i++) { + //得到当前差值 + curDiff = nums[i] - nums[i - 1]; + //如果当前差值和上一个差值为一正一负 + //等于0的情况表示初始时的preDiff + if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) { + count++; + preDiff = curDiff; + } + } + return count; + } +} diff --git a/src/main/java/heap/FindKthLargest.java b/src/main/java/heap/FindKthLargest.java index 1e352f8..12cc731 100644 --- a/src/main/java/heap/FindKthLargest.java +++ b/src/main/java/heap/FindKthLargest.java @@ -4,11 +4,11 @@ import java.util.Comparator; import java.util.PriorityQueue; /** - * 题目: 215. 数组中的第K个最大元素 (floodFill) + * 题目: 215. 数组中的第K个最大元素 (findKthLargest) * 描述:给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 * 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 * 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 - + * * 示例 1: 输入: [3,2,1,5,6,4], k = 2 输出: 5 @@ -28,7 +28,7 @@ public class FindKthLargest { return maxheap.peek(); } //使用最小堆来存储前 k 个最大的元素。堆顶元素是 k 个最大元素中的最小值。这样,堆的大小始终保持为 k。当堆的大小大于 k 时,弹出堆顶元素。最终堆顶元素就是第 k 大的元素。不需要完全填满堆再删除元素: - public int findKthLargest(int[] nums, int k) { + public int findKthLargest2(int[] nums, int k) { // 使用最小堆 PriorityQueue minHeap = new PriorityQueue<>(); @@ -47,4 +47,43 @@ public class FindKthLargest { // 返回堆顶元素,即为第 k 大的元素 return minHeap.peek(); } + //快速选择 + public int quickselect(int[] nums, int l, int r, int k) { + // 当区间内只有一个元素时,直接返回该元素 + if (l >= r) { + return nums[l]; + } + // 选取区间第一个元素作为枢轴 + int pivot = nums[l]; + int i = l, j = r; + + // 分区过程:调整数组,使得左侧的元素不大于枢轴,右侧的元素不小于枢轴 + while (i < j) { + // 从右边向左扫描,找到第一个小于 pivot 的元素,放到左侧 + while (i < j && nums[j] >= pivot) { + j--; + } + nums[i] = nums[j]; + // 从左边向右扫描,找到第一个大于 pivot 的元素,放到右侧 + while (i < j && nums[i] <= pivot) { + i++; + } + nums[j] = nums[i]; + } + // 将枢轴放入正确的位置 + nums[i] = pivot; + + // 现在 i 即为枢轴位置 + if (i == k) { + return nums[i]; + } else if (k < i) { + return quickselect(nums, l, i - 1, k); + } else { + return quickselect(nums, i + 1, r, k); + } + } + public int findKthLargest(int[] _nums, int k) { + int n = _nums.length; + return quickselect(_nums, 0, n - 1, n - k); + } } diff --git a/src/main/java/heap/TopKFrequent.java b/src/main/java/heap/TopKFrequent.java new file mode 100644 index 0000000..7a1c9e0 --- /dev/null +++ b/src/main/java/heap/TopKFrequent.java @@ -0,0 +1,40 @@ +package heap; + +import java.util.HashMap; +import java.util.Map; +import java.util.PriorityQueue; + +/** + * 题目: 347. 前 K 个高频元素 (topKFrequent) + * 描述:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 + + * 示例 1: + 输入: nums = [1,1,1,2,2,3], k = 2 + 输出: [1,2] + + * 链接:https://leetcode.cn/problems/top-k-frequent-elements/ + */ +public class TopKFrequent { + public int[] topKFrequent(int[] nums, int k) { + HashMapmap=new HashMap<>(); + PriorityQueue minHeap = new PriorityQueue<>( + (a, b) -> b[1] - a[1]); + int[] res=new int[k]; + int i=0; + for (int num : nums) { + if(!map.containsKey(num)) + map.put(num,1); + else + map.put(num,map.get(num)+1); + } + for (Map.Entry entry : map.entrySet()) { + minHeap.add(new int[]{entry.getKey(),entry.getValue()}); + } + while (!minHeap.isEmpty()) { + if(ii ; j--) { + if (arr[j-1]>arr[j]){ + swap(arr,j-1,j); + flag=true; + } + } + //本趟遍历后没有发生交换,说明表已经有序 + if (!flag){ + return; + } + } + } + private void swap(int[] arr,int i,int j){ + int temp=arr[i]; + arr[i]=arr[j]; + arr[j]=temp; + } +} diff --git a/src/main/java/sort/MergeSort.java b/src/main/java/sort/MergeSort.java new file mode 100644 index 0000000..4db6e67 --- /dev/null +++ b/src/main/java/sort/MergeSort.java @@ -0,0 +1,56 @@ +package sort; + +import java.util.Arrays; + +public class MergeSort { + + /** + * 归并排序(入口函数) + * @param arr 待排序数组 + */ + public static void mergeSort(int[] arr) { + if (arr == null || arr.length <= 1) { + return; // 边界条件 + } + int[] temp = new int[arr.length]; // 辅助数组 + mergeSort(arr, 0, arr.length - 1, temp); + } + + private static void mergeSort(int[] arr, int left, int right, int[] temp) { + if (left < right) { + int mid = (right + left) / 2; + mergeSort(arr, left, mid, temp); // 递归左子数组 + mergeSort(arr, mid + 1, right, temp); // 递归右子数组 + merge(arr, left, mid, right, temp); // 合并两个有序子数组 + } + } + + private static void merge(int[] arr, int left, int mid, int right, int[] temp) { + int i = left; // 左子数组起始指针 + int j = mid + 1; // 右子数组起始指针 + int t = 0; // 辅助数组指针 + + // 1. 按序合并两个子数组到temp + while (i <= mid && j <= right) { + if (arr[i] <= arr[j]) { // 注意等号保证稳定性 + temp[t++] = arr[i++]; + } else { + temp[t++] = arr[j++]; + } + } + + // 2. 将剩余元素拷贝到temp + while (i <= mid) { + temp[t++] = arr[i++]; + } + while (j <= right) { + temp[t++] = arr[j++]; + } + + // 3. 将temp中的数据复制回原数组 + t = 0; + while (left <= right) { + arr[left++] = temp[t++]; + } + } +} diff --git a/src/main/java/sort/QuickSort.java b/src/main/java/sort/QuickSort.java new file mode 100644 index 0000000..719a7c3 --- /dev/null +++ b/src/main/java/sort/QuickSort.java @@ -0,0 +1,46 @@ +package sort; + +public class QuickSort { + + // 交换数组中两个元素的位置 + public void quickSort(int[] arr, int begin, int end) { + if (begin >= end) { + return; + } + //划分为满足上述条件的两个子表,返回基准位置 + int pos=partition(arr,begin,end); + //对两个子表进行递归排序 + quickSort(arr, begin, pos - 1); + quickSort(arr, pos + 1, end); + } + //划分左右子序列,返回基准位置 + public int partition(int[] arr, int i, int j){ + int temp = arr[i]; + while (i < j) { + //在右边找到小于temp的放到左边 + while (i < j && arr[j] >= temp) { + j--; + } + arr[i] = arr[j]; + //在左边找到大或等于于temp的放到右边 + while (i < j && arr[i] <= temp) { + i++; + } + arr[j] = arr[i]; + } + //将temp放在剩下的基准位置i、j均可 + arr[i] = temp; + return i; + } + + public static void main(String[] args) { + int[] arr = {49, 38, 65, 97, 76, 13, 27, 49}; + QuickSort solution = new QuickSort(); + solution.quickSort(arr, 0, arr.length - 1); + + System.out.println("\n排序后:"); + for (int num : arr) { + System.out.print(num + " "); + } + } +} diff --git a/src/test/java/greedy/FindContentChildrenTest.java b/src/test/java/greedy/FindContentChildrenTest.java new file mode 100644 index 0000000..cb1299b --- /dev/null +++ b/src/test/java/greedy/FindContentChildrenTest.java @@ -0,0 +1,15 @@ +package greedy; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class FindContentChildrenTest { + + @Test + public void findContentChildren() { + int[] g = {1,2,3}, s = {1,1}; + FindContentChildren solution = new FindContentChildren(); + int res=solution.findContentChildren(g,s); + } +} \ No newline at end of file