leecode更新
This commit is contained in:
parent
015e83793d
commit
cf862785bf
|
|
@ -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;//移动到下一个需要操作的位置
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Character, Integer> 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<Character, Integer> 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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];//<min,max>
|
||||
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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue