diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T13_RemoveNthFromEnd.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T13_RemoveNthFromEnd.java new file mode 100644 index 0000000..5e8c814 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T13_RemoveNthFromEnd.java @@ -0,0 +1,64 @@ +package com.markilue.leecode.hot100; + +import com.markilue.leecode.listnode.ListNode; +import com.markilue.leecode.listnode.ListNodeUtils; +import org.junit.Test; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100 + *@Author: markilue + *@CreateTime: 2023-03-03 10:11 + *@Description: + * TODO 力扣19题 删除链表的倒数第N个节点: + * 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 + *@Version: 1.0 + */ +public class T13_RemoveNthFromEnd { + + @Test + public void test(){ + ListNode root = ListNodeUtils.build(new int[]{1, 2, 3, 4, 5}); + ListNode listNode = removeNthFromEnd(root, 6); + ListNodeUtils.print(listNode); + } + + /** + * 快慢指针:一个先走N步,然后两个指针一起走 + * @param head + * @param n + * @return + */ + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode fakeHead = new ListNode(); + fakeHead.next = head; + + ListNode fast = fakeHead; + ListNode slow = fakeHead; + + //快指针先走n步 + while (fast != null && n != 0) { + fast = fast.next; + n--; + } + //n不够 + if (fast == null) { + return fakeHead.next; + } + + //快指针走到头 + while (fast.next != null) { + fast = fast.next; + slow = slow.next; + } + + //删除slow + slow.next = slow.next.next; + + return fakeHead.next; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T14_IsValid.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T14_IsValid.java new file mode 100644 index 0000000..b1c17c6 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T14_IsValid.java @@ -0,0 +1,130 @@ +package com.markilue.leecode.hot100; + +import org.junit.Test; + +import java.util.*; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100 + *@Author: markilue + *@CreateTime: 2023-03-03 10:29 + *@Description: + * TODO 力扣20题 有效的括号: + * 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 + * 有效字符串需满足: + * 左括号必须用相同类型的右括号闭合。 + * 左括号必须以正确的顺序闭合。 + * 每个右括号都有一个对应的相同类型的左括号。 + *@Version: 1.0 + */ +public class T14_IsValid { + + @Test + public void test() { + String s = "()"; + System.out.println(isValid(s)); + } + + + /** + * 思路:核心就是对称消除 使用stack消栈 + * 速度击败48.96% 内存击败43.9% 2ms + * @param s + * @return + */ + public boolean isValid(String s) { + + char[] chars = s.toCharArray(); + + Stack stack = new Stack<>(); + Map map = new HashMap() {{ + put(')', '('); + put(']', '['); + put('}', '{'); + }}; + + for (char aChar : chars) { + if (!map.containsKey(aChar)) { + stack.push(aChar); + } else { + + if (stack.isEmpty() || map.get(aChar) != stack.pop()) {//这里记得将判空 + return false; + } + } + + } + + if (!stack.isEmpty()) {//这里也要记得加判空 + return false; + } + + return true; + + } + + + public boolean isValid1(String s) { + + char[] chars = s.toCharArray(); + + Deque stack = new LinkedList<>(); + Map map = new HashMap() {{ + put(')', '('); + put(']', '['); + put('}', '{'); + }}; + + for (char aChar : chars) { + if (!map.containsKey(aChar)) { + stack.push(aChar); + } else { + + if (stack.isEmpty() || map.get(aChar) != stack.pop()) {//这里记得将判空 + return false; + } + } + + } + + if (!stack.isEmpty()) {//这里也要记得加判空 + return false; + } + + return true; + + } + + + /** + * 官方优秀的解答:使用数组代替stack + * 速度击败100% 内存击败29.16% 0ms + * @param s + * @return + */ + public boolean isValid2(String s) { + if(s == null || s.length()==0){ + return true; + } + char[] str = s.toCharArray(); + int N = str.length; + int size = 0; + char[] stack=new char[N]; + for (int i=0;i result = new ArrayList<>(); + StringBuilder cur = new StringBuilder(); + + + /** + * 思路:有效的括号 实际上就是前面的(要比)要多那就是有效的括号 + * 速度击败75.47% 内存击败39.67% 1ms + * @param n + * @return + */ + public List generateParenthesis(int n) { + backtracking(n, 0, 0); + return result; + } + + /** + * + * @param n 需要生成多少对括号 + * @param x 当前有多少个( + * @param y 当前有多少个) + */ + public void backtracking(int n, int x, int y) { + if (x < y || x > n || y > n) { + //非有效括号 + return; + } + if (n == x && n == y) { + //遍历完了,并且符合要求 + result.add(new String(cur)); + return; + } + + for (int i = 0; i < 2; i++) { + if (i == 0) { + cur.append('('); + backtracking(n, x + 1, y); + } else { + cur.append(')'); + backtracking(n, x, y + 1); + } + cur.deleteCharAt(cur.length() - 1);//回溯 + } + + } + + + /** + * 官方最快:本质上与本人一致,只是把判断简化了 + * 速度击败100% 内存击败66.13% 0ms + * @param n + * @return + */ + public List generateParenthesis1(int n) { + List result = new ArrayList<>(); + StringBuilder sb = new StringBuilder(); + backTrack(result, sb, 0, 0, n); + return result; + } + + private void backTrack(List result, StringBuilder sb, int left, int right, int n) { + + if (sb.length() == n * 2) { + result.add(sb.toString()); + return; + } + + if (left < n) { + sb.append('('); + backTrack(result, sb, left + 1, right, n); + sb.deleteCharAt(sb.length() - 1); + } + + if (right < left) { + sb.append(')'); + backTrack(result, sb, left, right + 1, n); + sb.deleteCharAt(sb.length() - 1); + } + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T17_MergeKLists.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T17_MergeKLists.java new file mode 100644 index 0000000..9222ef2 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T17_MergeKLists.java @@ -0,0 +1,118 @@ +package com.markilue.leecode.hot100; + +import com.markilue.leecode.listnode.ListNode; +import com.markilue.leecode.listnode.ListNodeUtils; +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100 + *@Author: markilue + *@CreateTime: 2023-03-03 11:18 + *@Description: + * TODO 力扣23题 合并k个升序链表: + * 给你一个链表数组,每个链表都已经按升序排列。 + * 请你将所有链表合并到一个升序链表中,返回合并后的链表。 + *@Version: 1.0 + */ +public class T17_MergeKLists { + + @Test + public void test() { + ListNode[] listNodes = new ListNode[3]; + listNodes[0] = ListNodeUtils.build(new int[]{1, 4, 5}); + listNodes[1] = ListNodeUtils.build(new int[]{1,3,4}); + listNodes[2] = ListNodeUtils.build(new int[]{2, 6}); + ListNodeUtils.print(mergeKLists(listNodes)); + + } + + + /** + * 思路:二分法再合并 + * 速度击败74.86% 内存击败96.99% 3ms + * @param lists + * @return + */ + public ListNode mergeKLists(ListNode[] lists) { + + if (lists.length == 0) { + return null; + } + + return split(lists, 0, lists.length - 1); + } + + public ListNode split(ListNode[] lists, int start, int end) { + if (start == end) { + return lists[start]; + } + int mid = start + ((end - start) >> 1); + ListNode left = split(lists, start, mid); + ListNode right = split(lists, mid + 1, end); + + return merge(left, right); + + } + + public ListNode merge(ListNode list1, ListNode list2) { + + if (list1 == null) { + return list2; + } + if (list2 == null) { + return list1; + } + + ListNode root = new ListNode(); + if (list1.val < list2.val) { + root.val = list1.val; + root.next = merge(list1.next, list2); + } else { + root.val = list2.val; + root.next = merge(list1, list2.next); + } + + return root; + } + + + /** + * 官方最快:同样是分治法 + * 速度击败80.97% 内存击败32.68% 2ms + * @param lists + * @return + */ + public ListNode mergeKLists1(ListNode[] lists) { + if(lists == null || lists.length == 0){ + return null; + } + return merge(lists,0,lists.length - 1); + } + + public ListNode merge(ListNode[] lists , int left , int right){ + if(left == right) {return lists[left];} + int middle = left + (right - left)/2; + ListNode list1 = merge(lists,left,middle); + ListNode list2 = merge(lists,middle + 1,right); + return mergeTwoList(list1,list2); + } + + + public ListNode mergeTwoList(ListNode head1, ListNode head2){ + ListNode dummy = new ListNode(); + ListNode cur = dummy; // cur指向当前合并链表的最后一个 + while(head1!=null && head2!=null){ + if(head1.val <= head2.val){ + cur.next = head1; + head1 = head1.next; + }else{ + cur.next = head2; + head2 = head2.next; + } + cur = cur.next; + } + cur.next = head1==null?head2:head1; + return dummy.next; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/T18_NextPermutation.java b/Leecode/src/main/java/com/markilue/leecode/hot100/T18_NextPermutation.java new file mode 100644 index 0000000..7891d2c --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/T18_NextPermutation.java @@ -0,0 +1,150 @@ +package com.markilue.leecode.hot100; + +import org.junit.Test; + +import java.util.Arrays; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100 + *@Author: markilue + *@CreateTime: 2023-03-03 11:40 + *@Description: + * TODO 力扣31题 下一个排列: + * 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 + * 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 + * 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。 + * 更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中, + * 那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。 + * 如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。 + * 例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。 + * 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。 + * 而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。 + * 给你一个整数数组 nums ,找出 nums 的下一个排列。 + * 必须 原地 修改,只允许使用额外常数空间。 + *@Version: 1.0 + */ +public class T18_NextPermutation { + + @Test + public void test1(){ +// int[] nums ={1,2,3}; + int[] nums ={3,2,1}; + nextPermutation(nums); + System.out.println(Arrays.toString(nums)); + } + + + /** + * 思路:从后往前遍历,寻找第一个当前数比前一个数大的,进行交换 ; 如果找不到就进行整体的排序 + * 有问题: 没有想象的那么简单 + * 还有一个思路是: 先有小到大排序 通过回溯(树层去重后),找到原来的数,那么回溯的下一个值就是需要的值 + * 这有一个问题就是 使用了额外的空间 ,第二是时间复杂度应该为O(2^N) + * @param nums + */ + public void nextPermutation(int[] nums) { + + int i = nums.length - 1; + for (; i > 0; i--) { + if (nums[i] > nums[i - 1]) { + exchange(nums, i, i - 1); + break; + } + } + + if (i == 0) { + quickSort(nums); + } + } + + @Test + public void test(){ + int[] nums={5,6,4,8,2,9,1,7,3}; + quickSort(nums); + System.out.println(Arrays.toString(nums)); + } + + public void quickSort(int[] nums) { + + partition(nums,0,nums.length-1); + + } + + public void partition(int[] nums, int i, int j) { + if (i >= j) { + return; + } + int mid = sort(nums, i, j); + partition(nums, i, mid - 1);//排左边 + partition(nums, mid + 1, j);//排右边 + } + + public int sort(int[] nums, int i, int j) { + int left = i; + int right = j+1; + int num = nums[i]; + + while (left < right) { + + while (left < j && nums[++left] < num) { + continue; + } + + while (0 < right && nums[--right] > num) { + continue; + } + if (left >= right) { + break; + } + exchange(nums, left, right); + + } + exchange(nums, right, i); + return right; + } + + public void exchange(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + + /** + * 官方解答的思路:两边扫描,具体看笔记 + * 速度击败100% 内存击败58.73% 0ms + * @param nums + */ + public void nextPermutation1(int[] nums) { + int i = nums.length - 2; + while (i >= 0 && nums[i] >= nums[i + 1]) { + i--; + } + if (i >= 0) { + int j = nums.length - 1; + while (j >= 0 && nums[i] >= nums[j]) { + j--; + } + swap(nums, i, j); + } + reverse(nums, i + 1); + + } + + + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + public void reverse(int[] nums, int start) { + int left = start, right = nums.length - 1; + while (left < right) { + swap(nums, left, right); + left++; + right--; + } + } + +} diff --git a/big_screen/Gas-turbine-Screen/src/assets/img/company/operator-company-icon.png b/big_screen/Gas-turbine-Screen/src/assets/img/company/operator-company-icon.png new file mode 100644 index 0000000..5f315be Binary files /dev/null and b/big_screen/Gas-turbine-Screen/src/assets/img/company/operator-company-icon.png differ