From 50cafa2cb512a5da505baf3095517e08489b3190 Mon Sep 17 00:00:00 2001 From: whai Date: Tue, 5 Mar 2024 15:40:04 +0800 Subject: [PATCH] Syn --- .../whaifree/leetCode/Greedy/LeetCode435.java | 108 +++++++++++++++++ .../whaifree/leetCode/Greedy/LeetCode452.java | 94 +++++++++++++++ .../whaifree/leetCode/Greedy/LeetCode56.java | 60 ++++++++++ .../whaifree/leetCode/Greedy/LeetCode763.java | 113 ++++++++++++++++++ .../redo/redo_24_3_1/LeetCode406.java | 97 ++++++++++++--- 5 files changed, 456 insertions(+), 16 deletions(-) create mode 100644 src/main/java/cn/whaifree/leetCode/Greedy/LeetCode435.java create mode 100644 src/main/java/cn/whaifree/leetCode/Greedy/LeetCode452.java create mode 100644 src/main/java/cn/whaifree/leetCode/Greedy/LeetCode56.java create mode 100644 src/main/java/cn/whaifree/leetCode/Greedy/LeetCode763.java diff --git a/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode435.java b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode435.java new file mode 100644 index 0000000..b412933 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode435.java @@ -0,0 +1,108 @@ +package cn.whaifree.leetCode.Greedy; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/3/4 15:46 + * @注释 + */ +public class LeetCode435 { + + @Test + public void test() { + // intervals = [[1,2],[2,3],[3,4],[1,3]] + int[][] ints = {{1, 2}, {1, 3}, {2, 3}, {3, 4}}; + System.out.println(new Solution1().eraseOverlapIntervals(ints)); + } + + class Solution { + public int eraseOverlapIntervals(int[][] intervals) { + Arrays.sort(intervals, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0] - o2[0]; + } + }); + + int sub = 0; + for (int i = 1; i < intervals.length; i++) { + if (intervals[i][0] <= intervals[i - 1][1]) { + sub++; + intervals[i][1] = Math.max(intervals[i - 1][1], intervals[i][1]); + }else { + intervals[i][1] = Math.max(intervals[i - 1][1], intervals[i][1]); + } + } + + return sub; + } + + } + + class Solution1 { + + /** + * 想象成一次性最多参加几个活动 + * 按照结束时间排序。 + * + * 每次right边界就是取最早活动结束的时间; + * 如果某次活动开始时间刚刚好比上一个活动结束的时间要晚,那么就能多参加一次活动 + * + * @param intervals + * @return + */ + public int eraseOverlapIntervals(int[][] intervals) { + Arrays.sort(intervals, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[1] - o2[1]; + } + }); + + int normalCount = 1; + int right = intervals[0][1]; + for (int i = 1; i < intervals.length; i++) { + // 如果这次活动的开始时间比上个活动结束的时间要早,那么这个活动就不参加了 + if (intervals[i][0] >= right) { + // 如果这次活动的开始时间比上个活动结束的时间要晚,那么这个活动就可以参加 + // 最新的结束时间更新为这个活动的结束时间 + right = intervals[i][1]; + normalCount++; + } + } + return intervals.length - normalCount; + } + + } + + class Solution2 { + public int eraseOverlapIntervals(int[][] intervals) { + Arrays.sort(intervals, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[1] - o2[1]; + } + }); + + int normalCount = 1; + for (int i = 1; i < intervals.length; i++) { + + if (intervals[i - 1][1] <= intervals[i][0]) { + normalCount++; + } else { + // i的右边界有不重合,则正常区间+1 + intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]); + } + } + + return intervals.length - normalCount; + } + + } + +} diff --git a/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode452.java b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode452.java new file mode 100644 index 0000000..2e9e282 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode452.java @@ -0,0 +1,94 @@ +package cn.whaifree.leetCode.Greedy; + +import org.junit.Test; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Comparator; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/3/4 14:25 + * @注释 + */ +public class LeetCode452 { + + @Test + public void test() { + // [[3,9],[7,12],[3,8],[6,8],[9,10],[2,9],[0,9],[3,9],[0,6],[2,8]] + int[][] ints = { + {3,9},{7,12},{3,8},{6,8},{9,10},{2,9},{0,9},{3,9},{0,6},{2,8} + }; + + + System.out.println(new Solution1().findMinArrowShots(ints)); + } + + class Solution { + /** + * + * 按照最近出从小到大排序,判断下一个区间是否有交集 + * - 有交集,取交集最小值作为都能bomb的点 + * - 没有交集 res++表示下一个区间的箭 + * @param points + * @return + */ + public int findMinArrowShots(int[][] points) { + // 先按首位从小到大排序,end为start结束,此区间全部bomb + Arrays.sort(points, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return Long.compare(o1[0], o2[0]); + } + }); + + int res = 1; + for (int i = 1; i < points.length; i++) { + + if (points[i][0] < points[i - 1][1]) { + // 新的区间,有交集 + points[i][1] = Math.min(points[i][1], points[i - 1][1]); + }else { + res++; + } + + } + + return res; + } + + } + + class Solution1 { + /** + * 按照最远处排序,判断下一元素是否在上一个的区间内,不是就res++ + * @param points + * @return + */ + public int findMinArrowShots(int[][] points) { + //按最远处从小到大排序 + Arrays.sort(points, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + //-2147483646,-2147483645],[2147483646,2147483647 这个用例 + return Long.compare(o1[1], o2[1]); + } + }); + + int res = 1; + int right = points[0][1]; + for (int i = 1; i < points.length; i++) { + if (points[i][0] <= right) { + //当前箭能够射穿这个气球 + continue; + } + res++; + right = points[i][1]; + } + + return res; + } + + } +} diff --git a/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode56.java b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode56.java new file mode 100644 index 0000000..e9f9d74 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode56.java @@ -0,0 +1,60 @@ +package cn.whaifree.leetCode.Greedy; + +import org.junit.Test; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/3/5 12:09 + * @注释 + */ +public class LeetCode56 { + + @Test + public void test() { + int[][] intervals = new int[][]{{1, 3}, {5, 6}}; + for (int[] ints : new Solution().merge(intervals)) { + System.out.println(Arrays.toString(ints)); + } + } + + class Solution { + public int[][] merge(int[][] intervals) { + + Arrays.sort(intervals, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0] - o2[0]; + } + }); + + + List res = new ArrayList<>(); + for (int i = 1; i < intervals.length; i++) { + if (intervals[i - 1][1] < intervals[i][0]) { + res.add(intervals[i - 1]); + } else { + intervals[i][0] = intervals[i - 1][0]; // 已经排序过了,所以前一个的pre一定比这个的pre大 + intervals[i][1] = Math.max(intervals[i - 1][1], intervals[i][1]); + } + } + res.add(intervals[intervals.length - 1]); + +// int[][] result = new int[res.size()][2]; +// for (int i = 0; i < res.size(); i++) { +// result[i] = res.get(i); +// } +// return result; + + return res.toArray(new int[res.size()][2]); + } + + } + +} diff --git a/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode763.java b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode763.java new file mode 100644 index 0000000..93fa2f9 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Greedy/LeetCode763.java @@ -0,0 +1,113 @@ +package cn.whaifree.leetCode.Greedy; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * @version 1.0 + * @Author whai文海 + * @Date 2024/3/5 11:03 + * @注释 + */ +public class LeetCode763 { + @Test + public void test() { + new Solution1().partitionLabels("ababcbacadefegdehijhklij").forEach( + i -> { + System.out.println(i); + } + ); + + } + // 即最多能砍s多少刀?使得同一字母都出现在一个片段。 + public List partitionLabels(String s) { + // 统计 每个字符最远出现的位置, + char[] chars = s.toCharArray(); + int[] map = new int[26]; + for (int i = 0; i < chars.length; i++) { + map[chars[i] - 'a'] = i; + } + + List res = new ArrayList<>(); + + // 再遍历idx(最远的下标)前面找到最远出现的位置==当前i 就是一个切断点 + int left = -1; // 标记左边界 + int far = 0; // 标记最远出现的 + for (int i = 0; i < chars.length; i++) { + far = Math.max(far, map[chars[i] - 'a']); // far 表示最远边界, + // 最远出现的 和 当前索引一样,证明找到分割点 + if (far == i) { + res.add(i - left); + left = i; + } + } + + return res; + } + + + class Solution1 { + + /** + * 先统计每个字符最早最晚出现的位置 + * @param s + * @return + */ + public List partitionLabels(String s) { + int[][] partitions = staticLabel(s.toCharArray()); + List res = new ArrayList<>(); + Arrays.sort(partitions, (o1, o2) -> Integer.compare(o1[0], o2[0])); + int right = partitions[0][1]; + int left = 0; + for (int i = 0; i < partitions.length; i++) { + if (partitions[i][0] > right) { + //左边界大于右边界即可纪委一次分割 + res.add(right - left + 1); + left = partitions[i][0]; + } + right = Math.max(right, partitions[i][1]); + + } + //最右端 + res.add(right - left + 1); + return res; + } + + public int[][] staticLabel(char[] chars) { + int[][] map = new int[26][2]; + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + if (map[c - 'a'][0] == 0) { + map[c - 'a'][0] = i; + } + map[c - 'a'][1] = i;//最远出现 + + //第一个元素区别对待一下 + map[chars[0] - 'a'][0] = 0; + } + + // 去除字符串中未出现的字母所占用区间 + List temp = new ArrayList<>(); + List> h = new LinkedList<>(); + //组装区间 + for (int i = 0; i < 26; i++) { + temp.clear(); + temp.add(map[i][0]); + temp.add(map[i][1]); + h.add(new ArrayList<>(temp)); + } + int[][] res = new int[h.size()][2]; + for (int i = 0; i < h.size(); i++) { + List list = h.get(i); + res[i][0] = list.get(0); + res[i][1] = list.get(1); + } + + return map; + } + } +} diff --git a/src/main/java/cn/whaifree/redo/redo_24_3_1/LeetCode406.java b/src/main/java/cn/whaifree/redo/redo_24_3_1/LeetCode406.java index af3b65d..db3a3ce 100644 --- a/src/main/java/cn/whaifree/redo/redo_24_3_1/LeetCode406.java +++ b/src/main/java/cn/whaifree/redo/redo_24_3_1/LeetCode406.java @@ -61,20 +61,85 @@ public class LeetCode406 { } -class StringExer{ - String str = new String("good"); - char[] chars = {'a', 'b', 'c', 'd'}; +//class StringExer{ +// StringBuilder str = new StringBuilder("good"); +// char[] chars = {'a', 'b', 'c', 'd'}; +// +// public void change(StringBuilder str, char[] chars) { +// str = str.append("bad"); +// chars[0] = 'e'; +// } +// +// public static void main(String[] args) { +// StringExer stringExer = new StringExer(); +// stringExer.change(stringExer.str, stringExer.chars); +// System.out.println(stringExer.str.toString()); +// System.out.println(stringExer.chars); +// +// // 代码如下: +// char[] f = {'a', 's', 'd'}; +// +// String a = "asd"; // 常量池 +// String b = new String("asd"); // 字符串形式new +// String c = new String(f); // 数组形式new +// String d = new String(f).intern(); // 数组形式new,使用intern方法 +// String b2 = new String("asd").intern(); // 字符串形式new +// +// System.out.println(a + b + c + d); // 断点打在这里,只是为了防止jvm编译对代码优化 +// +// System.out.println(a == b); // false +// System.out.println(a == b2); // true +// System.out.println(a == d); // true +// System.out.println(b == d); // false +// System.out.println(c == d); // false +// +// +// String a1 = new String("abc"); +// String a2 = "abc"; +// System.out.println(a1 == a2); +// +// } +// +//} - public void change(String str, char[] chars) { - str = "bad"; - chars[0] = 'e'; - } - - public static void main(String[] args) { - StringExer stringExer = new StringExer(); - stringExer.change(stringExer.str, stringExer.chars); - System.out.println(stringExer.str); - System.out.println(stringExer.chars); - } - -} +//class ff { +// @Test +// public void main211() { +// +// /** +// * ① String s = new String("1") +// * 创建了两个对象 +// * 堆空间中一个new对象 +// * 字符串常量池中一个字符串常量"1"(注意:此时字符串常量池中已有"1") +// * ② s.intern()由于字符串常量池中已存在"1" +// * s指向的是堆空间中的对象地址 +// * s2 指向的是堆空间中常量池中"1"的地址 +// * 所以不相等 +// */ +// String s = new String("1"); +// s.intern(); // 这里 常量池已经存在1 +// String s2 = "1"; // 使用还是前面那个1 +// System.out.println(s==s2); // 一指向堆、一个指向常量池 +//// jdk1.6 false jdk7/8 false +// +// /* +// * ① String s3 = new String("1") + new String("1") +// * 等价于new String("11"),但是,常量池中并不生成字符串"11"; +// * +// * ② s3.intern() +// * 由于此时常量池中并无"11",所以把s3中记录的对象的地址存入常量池 +// * 所以s3 和 s4 指向的都是一个地址 +// */ +// String s3 = new String("1") + new String("1"); +//// 执行完后 常量池中不存在11 +// s3.intern(); // 让常量池中存在11; +//// 1. 在jdk6中,intern() 如果没有,会复制一份放入 +//// 2. 在jdk7之后,intern() 如果没有,会把对象引用地址复制一份放入串池,不会创建对象 +// String s4 = "11"; // 使用上一行代码生成的11 +// System.out.println(s3==s4); +////jdk1.6 false jdk7/8 true +// +// } +// +// +//}