From 03bc9f9c6bdeddd7901111219d0f94d89bf49b45 Mon Sep 17 00:00:00 2001 From: markilue <745518019@qq.com> Date: Sat, 22 Apr 2023 13:50:32 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../second/T04_4_FindMedianSortedArrays.java | 57 ++++++ .../leecode/hot100/second/T10_10_IsMatch.java | 59 +++++++ .../hot100/second/T11_15_ThreeSum.java | 56 ++++++ .../second/T12_17_LetterCombinations.java | 57 ++++++ .../second/T13_19_RemoveNthFromEnd.java | 41 +++++ .../leecode/hot100/second/T14_20_IsValid.java | 44 +++++ .../hot100/second/T15_21_MergeTwoLists.java | 41 +++++ .../second/T16_22_GenerateParenthesis.java | 55 ++++++ .../meituan/LC_25_ReverseKGroup.java | 69 ++++++++ .../leecode/interview/meituan/LC_45_Jump.java | 64 +++++++ .../interview/meituan/LC_71_SimplifyPath.java | 164 ++++++++++++++++++ .../leecode/listnode/selftry/ReorderList.java | 9 + .../listnode/selftry/ReorderListII.java | 38 ++++ .../com/markilue/interview/Question1.java | 112 ++++++++---- 14 files changed, 836 insertions(+), 30 deletions(-) create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T04_4_FindMedianSortedArrays.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T10_10_IsMatch.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T11_15_ThreeSum.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T12_17_LetterCombinations.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T13_19_RemoveNthFromEnd.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T14_20_IsValid.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T15_21_MergeTwoLists.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/hot100/second/T16_22_GenerateParenthesis.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_25_ReverseKGroup.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_45_Jump.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_71_SimplifyPath.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderListII.java diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T04_4_FindMedianSortedArrays.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T04_4_FindMedianSortedArrays.java new file mode 100644 index 0000000..9d8f5e6 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T04_4_FindMedianSortedArrays.java @@ -0,0 +1,57 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-20 11:28 + *@Description: + * TODO 力扣4题 寻找两个正序数组的中位数: + * 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 + * 算法的时间复杂度应该为 O(log (m+n)) 。 + *@Version: 1.0 + */ +public class T04_4_FindMedianSortedArrays { + + @Test + public void test(){ + int[] nums1={1,3}; + int[] nums2={2}; + System.out.println(findMedianSortedArrays(nums1,nums2)); + } + + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int n = nums1.length; + int m = nums2.length; + int left = (n + m + 1) / 2; + int right = (n + m + 2) / 2; + ////将偶数和奇数的情况合并,如果是奇数,会求两次同样的 k 。 + //比如n=5,m=5,则left=5,right=6; 合理 + //比如n=5,m=6,则left=6,right=6; 合理 + return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5; + + + } + + private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) { + int len1 = end1 - start1 + 1; + int len2 = end2 - start2 + 1; + //保证如果数组空了,就一定是len1 + if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k); + if (len1 == 0) return nums2[start2 + k - 1]; + + if (k == 1) return Math.min(nums1[start1], nums2[start2]); + //会直接比较k/2的位置 + int i = start1 + Math.min(len1, k / 2) - 1; + int j = start2 + Math.min(len2, k / 2) - 1; + + if (nums1[i] > nums2[j]) { + return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));//j-start2+1就抛弃的长度 + } else { + return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));//i - start1 + 1就是抛弃的长度 + } + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T10_10_IsMatch.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T10_10_IsMatch.java new file mode 100644 index 0000000..174f92b --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T10_10_IsMatch.java @@ -0,0 +1,59 @@ +package com.markilue.leecode.hot100.second; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-20 11:57 + *@Description: + * TODO 力扣10 正则表达式匹配: + * 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。 + * '.' 匹配任意单个字符 + * '*' 匹配零个或多个前面的那一个元素 + * 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。 + *@Version: 1.0 + */ +public class T10_10_IsMatch { + + /** + * 动态规划法:dp[i][j]表示使用s[0-i]和p[0-j]能否匹配上 + * @param s + * @param p + * @return + */ + public boolean isMatch(String s, String p) { + int m = s.length(); + int n = p.length(); + + boolean[][] dp = new boolean[m + 1][n + 1]; + dp[0][0] = true; + + for (int i = 0; i < dp.length; i++) { + for (int j = 1; j < dp[0].length; j++) { + if (p.charAt(j - 1) == '*') { + dp[i][j] = dp[i][j - 2];//不匹配字符,将该组合扔掉,不再进行匹配。 + if (matches(s, p, i, j - 1)) { + //如果当前值还和上一个一样 + dp[i][j] |= dp[i - 1][j];////能匹配 s 末尾的一个字符,将该字符扔掉,而该组合还可以继续进行匹配; + } + } else { + if (matches(s, p, i, j)) { + dp[i][j] = dp[i - 1][j - 1]; + } + } + } + } + return dp[m][n]; + + } + + public boolean matches(String s, String p, int i, int j) { + if (i == 0) return false; + if (p.charAt(j - 1) == '.') { + return true; + } + + return s.charAt(i - 1) == p.charAt(j - 1); + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T11_15_ThreeSum.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T11_15_ThreeSum.java new file mode 100644 index 0000000..61c701f --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T11_15_ThreeSum.java @@ -0,0 +1,56 @@ +package com.markilue.leecode.hot100.second; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-22 11:10 + *@Description: + * TODO 力扣15 三数之和: + * 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 + * 你返回所有和为 0 且不重复的三元组。 + * 注意:答案中不可以包含重复的三元组。 + *@Version: 1.0 + */ +public class T11_15_ThreeSum { + + public List> threeSum(int[] nums) { + + Arrays.sort(nums); + + List> result = new ArrayList<>(); + + for (int i = 0; i < nums.length; i++) { + if (nums[i] > 0) break; + if (i != 0 && nums[i] == nums[i - 1]) { + continue; + } + + int left = i + 1; + int right = nums.length - 1; + + while (left < right) { + long sum = nums[left] + nums[right]; + if (-nums[i] < sum) { + //>0 + right--; + } else if (-nums[i] > sum) { + left++; + } else { + //刚好符合 + result.add(new ArrayList<>(Arrays.asList(nums[i], nums[left], nums[right]))); + while (left < right && nums[left] == nums[left + 1]) left++; + while (left < right && nums[right] == nums[right - 1]) right--; + left++; + right--; + } + } + } + + return result; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T12_17_LetterCombinations.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T12_17_LetterCombinations.java new file mode 100644 index 0000000..7e46be2 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T12_17_LetterCombinations.java @@ -0,0 +1,57 @@ +package com.markilue.leecode.hot100.second; + +import org.omg.CORBA.PUBLIC_MEMBER; + +import java.sql.Array; +import java.util.*; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-22 11:32 + *@Description: + * TODO 力扣17 电话号码的字母组合: + * 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 + * 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 + *@Version: 1.0 + */ +public class T12_17_LetterCombinations { + + Map> map = new HashMap() {{ + put('2', Arrays.asList('a', 'b', 'c')); + put('3', Arrays.asList('d', 'e', 'f')); + put('4', Arrays.asList('g', 'h', 'i')); + put('5', Arrays.asList('j', 'k', 'l')); + put('6', Arrays.asList('m', 'n', 'o')); + put('7', Arrays.asList('p', 'q', 'r', 's')); + put('8', Arrays.asList('t', 'u', 'v')); + put('9', Arrays.asList('w', 'x', 'y', 'z')); + }}; + + + List result = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + + public List letterCombinations(String digits) { + if (digits.length() == 0) return result; + backtracking(digits.toCharArray(), 0); + return result; + } + + public void backtracking(char[] chars, int startIndex) { + if (startIndex == chars.length) { + result.add(sb.toString()); + return; + } + + List list = map.get(chars[startIndex]); + + for (Character character : list) { + sb.append(character); + backtracking(chars, startIndex + 1); + sb.deleteCharAt(sb.length() - 1); + } + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T13_19_RemoveNthFromEnd.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T13_19_RemoveNthFromEnd.java new file mode 100644 index 0000000..74d94f3 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T13_19_RemoveNthFromEnd.java @@ -0,0 +1,41 @@ +package com.markilue.leecode.hot100.second; + +import com.markilue.leecode.listnode.ListNode; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-22 11:42 + *@Description: + * TODO 力扣19 删除链表的倒数第N个节点: + * 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 + *@Version: 1.0 + */ +public class T13_19_RemoveNthFromEnd { + + public ListNode removeNthFromEnd(ListNode head, int n) { + + ListNode fake = new ListNode(); + fake.next = head; + ListNode fast = fake; + ListNode slow = fake; + + while (fast != null && n-- > 0) { + fast = fast.next; + } + if (fast == null) { + //不够 + return head; + } + while (fast.next != null) { + //走到头 + fast = fast.next; + slow = slow.next; + } + slow.next = slow.next.next; + return fake.next; + + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T14_20_IsValid.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T14_20_IsValid.java new file mode 100644 index 0000000..ef5c7ea --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T14_20_IsValid.java @@ -0,0 +1,44 @@ +package com.markilue.leecode.hot100.second; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-22 11:50 + *@Description: + * TODO 力扣20 有效的括号: + * 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 + * 有效字符串需满足: + * 左括号必须用相同类型的右括号闭合。 + * 左括号必须以正确的顺序闭合。 + * 每个右括号都有一个对应的相同类型的左括号。 + *@Version: 1.0 + */ +public class T14_20_IsValid { + + public boolean isValid(String s) { + HashMap map = new HashMap() {{ + put('(', ')'); + put('[', ']'); + put('{', '}'); + }}; + + Deque stack = new ArrayDeque<>(); + + for (char c : s.toCharArray()) { + if (map.containsKey(c)) { + stack.push(map.get(c)); + } else { + if (stack.isEmpty() || c != stack.peek()) return false; + stack.pop(); + } + } + + return stack.size()==0; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T15_21_MergeTwoLists.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T15_21_MergeTwoLists.java new file mode 100644 index 0000000..fd7bdde --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T15_21_MergeTwoLists.java @@ -0,0 +1,41 @@ +package com.markilue.leecode.hot100.second; + +import com.markilue.leecode.listnode.ListNode; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-22 11:59 + *@Description: + * TODO 力扣21 合并两个有序链表: + * 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 + *@Version: 1.0 + */ +public class T15_21_MergeTwoLists { + + /** + * + * @param list1 + * @param list2 + * @return + */ + public ListNode mergeTwoLists(ListNode list1, ListNode list2) { + if (list1 == null) { + return list2; + } else if (list2 == null) { + return list1; + } + ListNode root = new ListNode(); + if (list1.val < list2.val) { + root.val = list1.val; + root.next = mergeTwoLists(list1.next, list2); + } else { + root.val = list2.val; + root.next = mergeTwoLists(list1, list2.next); + } + + return root; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T16_22_GenerateParenthesis.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T16_22_GenerateParenthesis.java new file mode 100644 index 0000000..bd65fa7 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T16_22_GenerateParenthesis.java @@ -0,0 +1,55 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-04-22 12:09 + *@Description: + * TODO 力扣22 括号生成: + * 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。 + *@Version: 1.0 + */ +public class T16_22_GenerateParenthesis { + + @Test + public void test() { + System.out.println(generateParenthesis(3)); + } + + List result = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + + + public List generateParenthesis(int n) { + backtracking(n, 0, 0); + return result; + } + + public void backtracking(int n, int left, int right) { + if (left > n || right > n || right > left) return; + if (left == n && right == n) { + result.add(sb.toString()); + return; + } + + if (left < n) { + sb.append('('); + backtracking(n, left + 1, right); + sb.deleteCharAt(sb.length() - 1); + } + + if (right < n) { + sb.append(')'); + backtracking(n, left, right + 1); + sb.deleteCharAt(sb.length() - 1); + } + + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_25_ReverseKGroup.java b/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_25_ReverseKGroup.java new file mode 100644 index 0000000..4116bdf --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_25_ReverseKGroup.java @@ -0,0 +1,69 @@ +package com.markilue.leecode.interview.meituan; + +import com.markilue.leecode.listnode.ListNode; +import com.markilue.leecode.listnode.ListNodeUtils; +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.interview.meituan + *@Author: markilue + *@CreateTime: 2023-04-21 11:12 + *@Description: + * TODO 力扣25 K 个一组翻转链表: + * 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 + * k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 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) { + + if (head == null) { + return head; + } + ListNode temp = head; + for (int i = 0; i < k; i++) { + if (temp == null) return head;//不足k个 + temp = temp.next; + } + + ListNode newHead = reverse(head, temp); + head.next = reverseKGroup(temp, k); + + return newHead; + + } + + /** + * 反转从head到end + * @param head + * @param end + * @return + */ + public ListNode reverse(ListNode head, ListNode end) { + if(head==null) return head; + + ListNode fake = new ListNode(); + ListNode temp = head; + + ListNode temp1; + + while (temp != end) { + temp1 = temp.next; + temp.next = fake.next; + fake.next = temp; + temp = temp1; + } + + return fake.next; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_45_Jump.java b/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_45_Jump.java new file mode 100644 index 0000000..f0ee473 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_45_Jump.java @@ -0,0 +1,64 @@ +package com.markilue.leecode.interview.meituan; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.interview.meituan + *@Author: markilue + *@CreateTime: 2023-04-21 11:41 + *@Description: TODO 力扣45 跳跃游戏II: + *@Version: 1.0 + */ +public class LC_45_Jump { + + @Test + public void test(){ + int[] nums={2,3,1,1,4}; + System.out.println(jump1(nums)); + } + + public int jump(int[] nums) { + if (nums.length == 1) { + return 0; + } + + int maxGet = nums[0]; + int lastGet = nums[0]; + int cur = 1; + for (int i = 1; i < nums.length - 1; i++) { + if (lastGet < i) { + cur++; + lastGet = maxGet; + } + maxGet = Math.max(maxGet, nums[i] + i); + if (maxGet >= nums.length - 1) return cur + 1; + } + + + return maxGet > nums.length - 1 ? cur : 0; + + } + + public int jump1(int[] nums) { + if (nums.length == 1) { + return 0; + } + + int maxGet = -1; + int lastGet = -1; + int cur = 0; + for (int i = 0; i < nums.length - 1; i++) { + if (lastGet < i) { + cur++; + lastGet = maxGet; + } + maxGet = Math.max(maxGet, nums[i] + i); + if (maxGet >= nums.length - 1) return cur ; + } + + + return maxGet >= nums.length - 1 ? cur : 0; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_71_SimplifyPath.java b/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_71_SimplifyPath.java new file mode 100644 index 0000000..16b70d9 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/interview/meituan/LC_71_SimplifyPath.java @@ -0,0 +1,164 @@ +package com.markilue.leecode.interview.meituan; + +import org.junit.Test; + +import java.io.IOException; +import java.io.StreamTokenizer; +import java.util.ArrayDeque; +import java.util.Deque; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.interview.meituan + *@Author: markilue + *@CreateTime: 2023-04-21 10:15 + *@Description: TODO 力扣71 简化路径 + *@Version: 1.0 + */ +public class LC_71_SimplifyPath { + + public static void main(String[] args) throws IOException { +// StreamTokenizer re = new StreamTokenizer(System.in); +// re.nextToken(); +// int int1 = (int)re.nval; +// System.out.println(int1); + for (int i = 0; i < 5; i++) { + new Thread(new Runnable(){ + public void run(){ + System.out.println(Thread.currentThread().getName()); + } + },"thread"+i).start(); + } + + + } + + @Test + public void test() { + String path = "/a/./b/../../c/"; + System.out.println(simplifyPath1(path)); + } + + @Test + public void test1() { + String path = "/home//foo/"; + System.out.println(simplifyPath2(path)); + } + + @Test + public void test2() { + String path = "/."; + System.out.println(simplifyPath(path)); + } + + @Test + public void test3() { + String path = "/abc"; + System.out.println(simplifyPath(path)); + } + + public String simplifyPath(String path) { + + StringBuilder sb = new StringBuilder(); + char[] chars = path.toCharArray(); + if (chars[0] == '/') { + sb.append('/'); + } + + for (int i = 1; i < chars.length; i++) { + if (Character.isLetterOrDigit(chars[i])) { + while (i < chars.length && (Character.isLetterOrDigit(chars[i]) || chars[i] == '_')) { + sb.append(chars[i]); + i++; + } + i--;//不是之后回退一步 + } else if (chars[i] == '.') { + + if (i + 1 < chars.length && chars[i + 1] == '.') { + for (int j = 0; j < 2; j++) { + if (sb.length() == 0) { + continue; + } + int index = sb.lastIndexOf("/"); + sb.delete(index, sb.length()); + } + i++; + } + } else if (chars[i] == '/') { + if (sb.length() == 0 || sb.charAt(sb.length() - 1) != '/') { + sb.append(chars[i]); + } + } + } + if (sb.length() == 0) { + sb.append('/'); + } + if (sb.length() > 1 && sb.charAt(sb.length() - 1) == '/') { + sb.deleteCharAt(sb.length() - 1); + } + + return sb.toString(); + + } + + + /** + * 官方题解:使用一个栈记录 + * 速度击败49.47% 内存击败43.46% 4ms + * @param path + * @return + */ + public String simplifyPath1(String path) { + String[] name = path.split("/"); + Deque stack = new ArrayDeque<>(); + + for (String s : name) { + if ("..".equals(s)) { + if (!stack.isEmpty()) { + stack.pollLast(); + } + } else if (s.length() > 0 && !".".equals(s)) { + stack.offerLast(s); + } + } + + StringBuilder sb = new StringBuilder(); + if (stack.isEmpty()) { + sb.append("/"); + } else { + while (!stack.isEmpty()) { + sb.append("/"); + sb.append(stack.pollFirst()); + } + } + + return sb.toString(); + + } + + //优秀解法:不用split,挨个找,也可以直接避免split之后有的为""的情况;速度击败98.98% 内存击败21.42% + public String simplifyPath2(String path) { + Deque deque = new ArrayDeque<>(); + int n = path.length(); + for (int i = 1; i < n; i++) { + if (path.charAt(i) == '/') continue; // 找到下一个不是"/"的位置 + int j = i + 1; // j指向下一个位置,双指针! + while (j < n && path.charAt(j) != '/') j++; // 直到j指向的位置是"/" + String temp = path.substring(i, j); // 左闭右开,[i.j) + if (temp.equals("..")) { //..的时候,栈内有元素才删 + if (!deque.isEmpty()) { + deque.pollLast(); + } + } else if (!(temp.equals("."))) { // .的时候就continue,这里省略了,不是.的时候就进栈 + deque.addLast(temp); + } + i = j; //j是指向"/"的,令i=j开始下一轮循环 + } + StringBuilder ans = new StringBuilder(); + while (!deque.isEmpty()) { // 还原栈内的路径 + ans.append("/"); + ans.append(deque.pollFirst()); + } + return ans.length() == 0 ? "/" : ans.toString(); // 栈为空就直接返回"/",否则返回ans.toString() + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderList.java b/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderList.java index 178f11b..c2886af 100644 --- a/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderList.java +++ b/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderList.java @@ -1,6 +1,8 @@ package com.markilue.leecode.listnode.selftry; import com.markilue.leecode.listnode.ListNode; +import com.markilue.leecode.listnode.ListNodeUtils; +import org.junit.Test; /** *@BelongsProject: Leecode @@ -18,6 +20,13 @@ import com.markilue.leecode.listnode.ListNode; */ public class ReorderList { + @Test + public void test() { + ListNode root = ListNodeUtils.build(new int[]{1, 2, 3, 4, 5}); + reorderList(root); + ListNodeUtils.print(root); + } + /** * 递归法 diff --git a/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderListII.java b/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderListII.java new file mode 100644 index 0000000..25568e0 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/listnode/selftry/ReorderListII.java @@ -0,0 +1,38 @@ +package com.markilue.leecode.listnode.selftry; + +import com.markilue.leecode.listnode.ListNode; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.listnode.selftry + *@Author: markilue + *@CreateTime: 2023-04-21 10:06 + *@Description: TODO + *@Version: 1.0 + */ +public class ReorderListII { + + + ListNode p; + + public void reorderList(ListNode head) { + p = head; + recur(head); + } + + public void recur(ListNode head) { + if (head == null) { + return; + } + recur(head.next); + + if (p.next == null || head == p || head.next == p) { + //已经运行到了 + p.next = null; + return; + } + head.next = p.next; + p.next = head; + p = p.next.next; + } +} diff --git a/interview/Huawei/src/main/java/com/markilue/interview/Question1.java b/interview/Huawei/src/main/java/com/markilue/interview/Question1.java index 9a997c3..40b9355 100644 --- a/interview/Huawei/src/main/java/com/markilue/interview/Question1.java +++ b/interview/Huawei/src/main/java/com/markilue/interview/Question1.java @@ -32,23 +32,23 @@ public class Question1 { return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0]; } }); - int res=0; + int res = 0; ArrayList single = new ArrayList<>(); ArrayList multi = new ArrayList<>(); for (int i = 0; i < nums.length; i++) { - if(nums[i][0]<=nums[i-1][1]){ - if(multi.size()>0&&nums[i][0] 0 && nums[i][0] < multi.get(multi.size() - 1)[1]) { + nums[i][0] = multi.get(multi.size() - 1)[1]; + if (nums[i][1] < nums[i - 1][1]) { int[] temp = nums[i]; - nums[i]=nums[i-1]; - nums[i-1]=temp; + nums[i] = nums[i - 1]; + nums[i - 1] = temp; } } - if(nums[i-1][0]!=nums[i][0])single.add(new int[]{nums[i-1][0],nums[i][0]}); - if(nums[i][0]!=nums[i-1][1])multi.add(new int[]{nums[i][0],nums[i-1][1]}); - }else { - single.add(nums[i-1]); + if (nums[i - 1][0] != nums[i][0]) single.add(new int[]{nums[i - 1][0], nums[i][0]}); + if (nums[i][0] != nums[i - 1][1]) multi.add(new int[]{nums[i][0], nums[i - 1][1]}); + } else { + single.add(nums[i - 1]); } } @@ -71,7 +71,7 @@ public class Question1 { public void test() { int[][] nums = new int[][]{{2, 5}, {8, 9}}; // int[][] nums = new int[][]{{4,8}, {1,6},{2,9}}; - solve(nums); + solve1(nums); } public void solve(int[][] nums) { @@ -93,18 +93,18 @@ public class Question1 { for (int i = 1; i < nums.length; i++) { if (last[1] > nums[i][0]) { - total.add(new int[]{last[0], nums[i][0]-1}); - condition.add(1); - if (nums[i][1] < last[1]) { - total.add(new int[]{nums[i][0], nums[i][1]}); - condition.add(2); - last[0] = nums[i][1]; - } else { - total.add(new int[]{nums[i][0], last[1]}); - condition.add(2); - last[0] = last[1]; - last[1] = nums[i][1]; - } + total.add(new int[]{last[0], nums[i][0] - 1}); + condition.add(1); + if (nums[i][1] < last[1]) { + total.add(new int[]{nums[i][0], nums[i][1]}); + condition.add(2); + last[0] = nums[i][1]; + } else { + total.add(new int[]{nums[i][0], last[1]}); + condition.add(2); + last[0] = last[1]; + last[1] = nums[i][1]; + } } else { total.add(new int[]{last[0], last[1]}); condition.add(1); @@ -119,14 +119,66 @@ public class Question1 { for (int i = 0; i < total.size(); i++) { int[] ints = total.get(i); Integer condition1 = condition.get(i); - if(condition1==0){ - result+=(ints[1]-ints[0]+1); - }else if(condition1==1){ - result+=(ints[1]-ints[0]+1)*3; - }else { - result+=(ints[1]-ints[0]+1)*4; + if (condition1 == 0) { + result += (ints[1] - ints[0] + 1); + } else if (condition1 == 1) { + result += (ints[1] - ints[0] + 1) * 3; + } else { + result += (ints[1] - ints[0] + 1) * 4; } } System.out.println(result); } + + + /** + * 后来重写的情况:两个用例应该是对了 + * @param nums + */ + public void solve1(int[][] nums) { + Arrays.sort(nums, new Comparator() { + @Override + public int compare(int[] o1, int[] o2) { + return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0]; + } + }); + + + int[] last = nums[0]; + + int result = 0; + + for (int i = 1; i < nums.length; i++) { + if (last[1] > nums[i][0]) { + if (nums[i][1] < last[0]) { + //特殊情况直接continue + continue; + } else if (nums[i][0] < last[0]) { + nums[i][0] = last[0];//直接归入 + } + //计算单任务部分 + result += (nums[i][0] - last[0]) * 3; + //计算多任务部分 + if (nums[i][1] < last[1]) { + result += (nums[i][1] - nums[i][0] + 1) * 4; + last[0] = nums[i][1] + 1; + } else { + result += (last[1] - nums[i][0] + 1) * 4; + last[0] = last[1] + 1; + last[1] = nums[i][1]; + } + } else { + //单任务部分 + result += (last[1] - last[0] + 1) * 3; + //无任务部分 + result += (nums[i][0] - last[1] - 1); + last = nums[i]; + } + } + + //最后加上单任务 + result += (last[1] - last[0] + 1) * 3; + + System.out.println(result); + } }