diff --git a/Week 07/id_281/LeetCode_1122_006.java b/Week 07/id_281/LeetCode_1122_006.java new file mode 100644 index 000000000..1514c3437 --- /dev/null +++ b/Week 07/id_281/LeetCode_1122_006.java @@ -0,0 +1,49 @@ +import java.util.Arrays; + +public class Solution { + /** + * 1. 开辟1001大小的数组空间,记为cache + * 2. 遍历arr1,进行计数 + * 3. 遍历arr2,作为索引到cache中获取值 + * @param arr1 + * @param arr2 + * @return + */ + public int[] relativeSortArray(int[] arr1, int[] arr2) { + if (arr1.length == 0) { + return arr1; + } + int[] cache = new int[Arrays.stream(arr1).max().getAsInt() + 1]; + for (int i : arr1) { + cache[i]++; + } + int[] res = new int[arr1.length]; + int index = 0; + // arr2的顺序 + for (int i : arr2) { + while (cache[i] > 0) { + res[index++] = i; + cache[i]--; + } + cache[i] = 0; + } + + // 剩余的arr1,需要由小到大排列 + for (int i = 0; i < cache.length; i++) { + while (cache[i] > 0) { + res[index++] = i; + cache[i]--; + } + } + return res; + } + + public static void main(String[] args) { + Solution solution = new Solution(); + int[] ints = solution.relativeSortArray(new int[]{28, 6, 22, 8, 44, 17}, new int[]{22, 28, 8, 6}); + System.out.println(Arrays.toString(ints)); + } + + + +} diff --git a/Week 07/id_281/LeetCode_146_006.java b/Week 07/id_281/LeetCode_146_006.java new file mode 100644 index 000000000..e0a774324 --- /dev/null +++ b/Week 07/id_281/LeetCode_146_006.java @@ -0,0 +1,117 @@ +import java.util.HashMap; +import java.util.Map; + +/** + * 使用双向链表和哈希表实现 +*/ +public class LRUCache { + + private static class DoubleList { + private static class Node { + int key; + int value; + Node prev, next; + + Node(int key, int value) { + this.key = key; + this.value = value; + } + } + + private Node head, tail; + private int size; + + DoubleList() { + head = new Node(0, 0); + tail = new Node(0, 0); + head.next = tail; + tail.prev = head; + } + + /** + * 加入链表头部 + * @param x + */ + void addFirst(Node x) { + x.next = head.next; + x.prev = head; + head.next.prev = x; + head.next = x; + size++; + } + + /** + * 删除指定节点 + * @param x + */ + void remove(Node x) { + x.prev.next = x.next; + x.next.prev = x.prev; + size--; + } + + /** + * 删除最后一个节点 + * @return + */ + Node removeLast() { + if (tail.prev == head) { + return null; + } + Node last = tail.prev; + remove(last); + return last; + } + } + + + private int capacity; + private Map map; + private DoubleList cache; + + public LRUCache(int capacity) { + this.capacity = capacity; + this.map = new HashMap<>(); + cache = new DoubleList(); + } + + /** + * 从哈希表中获取链表节点:Node , + * 从链表中删除该节点,放入链表头部 + * @param key + * @return + */ + public int get(int key) { + if (!map.containsKey(key)) { + return -1; + } + int value = map.get(key).value; + put(key, value); + return value; + } + + /** + * 判断链表是否达到capacity大小,达到了则删除最后一个节点之后,放入新节点 + * @param key + * @param value + */ + public void put(int key, int value) { + DoubleList.Node node = new DoubleList.Node(key, value); + if (map.containsKey(key)) { + // 删除旧节点 + cache.remove(map.get(key)); + // 添加新节点 + cache.addFirst(node); + map.put(key, node); + } else { + // 淘汰最后一个节点 + if (capacity == cache.size) { + DoubleList.Node last = cache.removeLast(); + map.remove(last.key); + } + map.put(key, node); + cache.addFirst(node); + } + } + +} diff --git a/Week 08/id_281/LeetCode_1143_281.java b/Week 08/id_281/LeetCode_1143_281.java new file mode 100644 index 000000000..0dbf68444 --- /dev/null +++ b/Week 08/id_281/LeetCode_1143_281.java @@ -0,0 +1,23 @@ +public int longestCommonSubsequence(String text1, String text2) { + int m = text1.length() + 1, n = text2.length() + 1; + int[] dp = new int[n]; + char[] text1Arr = ("#" + text1).toCharArray(); + char[] text2Arr = ("#" + text2).toCharArray(); + int temp, now; + for (int i = 1; i < m; i++) { + temp = 0; + for (int j = 1; j < n; j++) { + // 记录(i-1, j-1)位置的最长子序列长度 + now = dp[j]; + if (text1Arr[i] == text2Arr[j]) { + // 要去 (i-1, j-1) 位置的值 + dp[j] = temp + 1; + } else { + dp[j] = Math.max(dp[j-1], dp[j]); + } + // 记录(i-1, j-1)位置的最长子序列长度,传递到(i,j) + temp = now; + } + } + return dp[n-1]; +} diff --git a/Week 08/id_281/LeetCode_300_281.java b/Week 08/id_281/LeetCode_300_281.java new file mode 100644 index 000000000..eb0bbbad7 --- /dev/null +++ b/Week 08/id_281/LeetCode_300_281.java @@ -0,0 +1,32 @@ +// 2. 二分搜索 +// 此解法比较巧妙,作为扩展视野即可,关键还是要理解动态规划解法 +// 将 nums 里的数据非为k堆,需要满足: +// 1. 每堆需要从大到小 +// 2. 取 nums 里的一个新元素时,在已有的堆中找合适的放置位置,有的话放最左边的堆,如果没有开一个新的堆 +public int lengthOfLIS(int[] nums) { + // 存放每个堆的堆顶元素,会构成一个有序的数组 + int[] top = new int[nums.length]; + // 堆的数量 + int piles = 0; + + for (int item : nums) { + // 在堆中找合适的放置位置 + // 在多个堆中应用二分查找:找第一个大于等于 item 的元素 + int lo = 0, hi = piles; + while (lo < hi) { + int mid = lo + (hi - lo) / 2; + if (top[mid] > item) { + hi = mid; + } else if (top[mid] < item) { + lo = mid + 1; + } else { + hi = mid; + } + } + + if (lo == piles) piles++; + top[lo] = item; + } + + return piles; +}