diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_143_ReorderList.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_143_ReorderList.java new file mode 100644 index 0000000..0bb5781 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_143_ReorderList.java @@ -0,0 +1,41 @@ +package com.markilue.leecode.hot100.interviewHot.listnode; + +import com.markilue.leecode.listnode.ListNode; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.interviewHot.listnode + *@Author: markilue + *@CreateTime: 2023-05-12 10:49 + *@Description: TODO 力扣143 重排链表: + *@Version: 1.0 + */ +public class LC_143_ReorderList { + + ListNode p; + + //重复模式:寻找不变操作进行递归 + public void reorderList(ListNode head) { + p = head; + recur(head); + } + + public void recur(ListNode cur) { + if (cur == null) { + return; + } + + recur(cur.next);//深度优先直接找到最后面的 + + if (p.next == null || p == cur || cur.next == p) { + //遍历到中间了,不需要继续遍历了 + p.next = null; + return; + } + + //处理当前节点的逻辑 + cur.next = p.next; + p.next = cur; + p = p.next.next;//移动到下一个需要操作的位置 + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_25_ReverseKGroup.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_25_ReverseKGroup.java new file mode 100644 index 0000000..8773a31 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_25_ReverseKGroup.java @@ -0,0 +1,60 @@ +package com.markilue.leecode.hot100.interviewHot.listnode; + +import com.markilue.leecode.listnode.ListNode; +import com.markilue.leecode.listnode.ListNodeUtils; +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.interviewHot.listnode + *@Author: markilue + *@CreateTime: 2023-05-12 11:05 + *@Description: TODO 力扣25 K个一组翻转链表 + *@Version: 1.0 + */ +public class LC_25_ReverseKGroup { + + @Test + public void test() { + ListNode root = ListNodeUtils.build(new int[]{1, 2, 3, 4, 5}); + ListNodeUtils.print(reverseKGroup(root,2)); + } + + + //寻找循环不变量:本质上就是四个一组的操作,考虑使用递归 + public ListNode reverseKGroup(ListNode head, int k) { + + //k个一组,至少要保证head之后有k个 + ListNode temp = head; + for (int i = 0; i < k; i++) { + if (temp == null) return head;//没有k个不做任何处理 + temp = temp.next; + } + + //有k个,开始翻转这K个 + ListNode root = reverseNode(head, temp); + //因为调用了reverseNode,从这里开始head变成了k个一组中的最后一个了,所以后续翻转的拼到head后面 + head.next = reverseKGroup(temp, k);//翻转temp后面的 + + return root; + } + + public ListNode reverseNode(ListNode start, ListNode end) { + + //反转部分链表 + if (start == null) return start; + + ListNode fake = new ListNode(); + ListNode temp =start; + ListNode tempNext; + while (temp != end) { + tempNext = temp.next; + temp.next = fake.next; + fake.next = temp; + temp = tempNext; + } + + return fake.next; + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_84_DeleteDuplicatesII.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_82_DeleteDuplicatesII.java similarity index 60% rename from Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_84_DeleteDuplicatesII.java rename to Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_82_DeleteDuplicatesII.java index 2ee7ea2..fd580d1 100644 --- a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_84_DeleteDuplicatesII.java +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/listnode/LC_82_DeleteDuplicatesII.java @@ -10,7 +10,7 @@ import com.markilue.leecode.listnode.ListNode; *@Description: TODO 力扣82 删除排序链表中的重复元素II:重复全删 *@Version: 1.0 */ -public class LC_84_DeleteDuplicatesII { +public class LC_82_DeleteDuplicatesII { public ListNode deleteDuplicates(ListNode head) { ListNode fake = new ListNode(-101); @@ -30,4 +30,26 @@ public class LC_84_DeleteDuplicatesII { } return fake.next; } + + + //二刷 + public ListNode deleteDuplicates1(ListNode head) { + ListNode fake = new ListNode(-101); + fake.next = head; + ListNode cur = fake; + + while (cur.next != null && cur.next.next != null) { + if (cur.next.val == cur.next.next.val) { + ListNode temp = cur.next; + while (temp.next != null && temp.val == temp.next.val) { + temp = temp.next; + } + cur.next = temp.next; + } else { + cur = cur.next; + } + } + + return fake.next; + } } diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java index b0fcb9f..5bbb1a0 100644 --- a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/window/LC_76_MinWindow.java @@ -25,7 +25,7 @@ public class LC_76_MinWindow { @Test public void test1() { String s = "ADOBECODEBANC", t = "ABC"; - System.out.println(minWindow2(s, t)); + System.out.println(minWindow4(s, t)); } @@ -229,5 +229,53 @@ public class LC_76_MinWindow { return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len); + } + + //三刷 + public String minWindow4(String s, String t) { + //构造合适窗口 + HashMap need = new HashMap<>(); + for (int i = 0; i < t.length(); i++) { + char c = t.charAt(i); + need.put(c, need.getOrDefault(c, 0) + 1); + } + + HashMap window = new HashMap<>(); + int left = 0; + int right = 0; + int start = 0; + int len = Integer.MAX_VALUE; + int size = need.size(); + + while (right < s.length()) { + char c = s.charAt(right++); + if (need.containsKey(c)) { + window.put(c, window.getOrDefault(c, 0) + 1); + if (window.get(c).equals(need.get(c))) { + size--; + } + } + + while (size == 0 && left < right) { + //开始缩小窗口 + int cur = right - left;//因为之前right+1了所以这里不用+ + if (cur < len) { + len = cur; + start = left; + } + char c1 = s.charAt(left++); + if (need.containsKey(c1)) { + Integer num = window.get(c1); + if (num.equals(need.get(c1))) { + size++; + } + window.put(c1, num - 1); + } + } + } + + return len == Integer.MAX_VALUE ? "" : s.substring(start, start + len); + + } } diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T57_142_MaxProduct.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T57_142_MaxProduct.java new file mode 100644 index 0000000..19ea477 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T57_142_MaxProduct.java @@ -0,0 +1,61 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-12 11:31 + *@Description: TODO 力扣152 乘积最大子数组 + *@Version: 1.0 + */ +public class T57_142_MaxProduct { + + @Test + public void test() { + int[] nums = {2, 3, -2, 4}; + System.out.println(maxProduct(nums)); + } + + //由于是乘积:且数组有正有负,所以最小的也可以变成最大的,最大的也可以变成最小的 + public int maxProduct(int[] nums) { + + int[][] dp = new int[nums.length][2];// + dp[0][0] = nums[0]; + dp[0][1] = nums[0]; + int max = nums[0]; + + for (int i = 1; i < nums.length; i++) { + //当前位置,一定是要了当前的数的,通过max来中间的过程 + dp[i][0] = Math.min(Math.min(nums[i], dp[i - 1][0] * nums[i]), dp[i - 1][1] * nums[i]); + dp[i][1] = Math.max(Math.max(nums[i], dp[i - 1][0] * nums[i]), dp[i - 1][1] * nums[i]); + if (max < dp[i][1]) { + max = dp[i][1]; + } + + } + + return max; + } + + //滚动数组优化 + public int maxProduct1(int[] nums) { + + int dp0 = nums[0]; + int dp1 = nums[0]; + int max = nums[0]; + int temp; + for (int i = 1; i < nums.length; i++) { + //当前位置,一定是要了当前的数的,通过max来中间的过程 + temp = dp0; + dp0 = Math.min(Math.min(nums[i], dp0 * nums[i]), dp1 * nums[i]); + dp1 = Math.max(Math.max(nums[i], temp* nums[i]), dp1 * nums[i]); + if (max < dp1) { + max = dp1; + } + } + + return max; + } +}