129. Rehashing


1 /** 2 * Definition for ListNode 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { 7 * val = x; 8 * next = null; 9 * } 10 * } 11 */ 12 13 public class Solution { 14 /** 15 * @param hashTable: A list of The first node of linked list 16 * @return: A list of The first node of linked list which have twice size 17 */ 18 public ListNode[] rehashing(ListNode[] hashTable) { 19 // write your code here 20 if (hashTable.length == 0) { 21 return hashTable; 22 } 23 int capacity = hashTable.length * 2; 24 ListNode[] result = new ListNode[capacity]; 25 for (ListNode listNode : hashTable) { 26 while (listNode != null) { 27 int newIndex = (listNode.val % capacity + capacity) % capacity; 28 if (result[newIndex] == null) { 29 result[newIndex] = new ListNode(listNode.val); 30 } else { 31 ListNode head = result[newIndex]; 32 while (head.next != null) { 33 head = head.next; 34 } 35 head.next = new ListNode(listNode.val); 36 } 37 listNode = listNode.next; 38 } 39 } 40 return result; 41 } 42 };
134. LRU Cache


1 class Node { 2 int key; 3 int value; 4 Node next; 5 6 Node(int key, int value) { 7 this.key = key; 8 this.value = value; 9 this.next = null; 10 } 11 } 12 13 public class LRUCache { 14 int size; 15 int capacity; 16 Node tail; 17 Node dummy; 18 Map<Integer, Node> keyToPrevMap; 19 20 /* 21 * @param capacity: An integer 22 */ 23 public LRUCache(int capacity) { 24 // do intialization if necessary 25 this.capacity = capacity; 26 this.size = 0; 27 this.dummy = new Node(0, 0); 28 this.tail = dummy; 29 keyToPrevMap = new HashMap<>(); 30 } 31 32 public void moveRecentNodeToTail(int key) { 33 Node prev = keyToPrevMap.get(key); 34 Node curr = prev.next; 35 if (curr == tail) { 36 return; 37 } 38 39 prev.next = curr.next; 40 tail.next = curr; 41 keyToPrevMap.put(key, tail); 42 //删掉现节点之后,不仅要改变前指针指向,还需要更新map 43 if(prev.next!=null){ 44 keyToPrevMap.put(prev.next.key,prev); 45 } 46 tail = curr; 47 } 48 49 /* 50 * @param key: An integer 51 * @return: An integer 52 */ 53 public int get(int key) { 54 // write your code here 55 if (keyToPrevMap.containsKey(key)) { 56 moveRecentNodeToTail(key); 57 return tail.value; 58 } 59 return -1; 60 } 61 62 /* 63 * @param key: An integer 64 * @param value: An integer 65 * @return: nothing 66 */ 67 public void set(int key, int value) { 68 // write your code here 69 if (get(key) != -1) { 70 Node prev = keyToPrevMap.get(key); 71 prev.next.value = value; 72 return; 73 } 74 75 //无此值 set并放在队尾 76 if (size < capacity) { 77 size++; 78 Node newNode = new Node(key, value); 79 tail.next = newNode; 80 keyToPrevMap.put(key, tail); 81 tail = newNode; 82 return; 83 } 84 85 //空间已满,需要删掉头指针: 可以直接替换头指针key-value值,再移到队尾来实现 86 Node first = dummy.next; 87 keyToPrevMap.remove(first.key); 88 first.key = key; 89 first.value = value; 90 keyToPrevMap.put(key, dummy); 91 moveRecentNodeToTail(key); 92 } 93 }
4. Ugly Number II
method1:用优先队列


1 public class Solution { 2 /** 3 * @param n: An integer 4 * @return: the nth prime number as description. 5 */ 6 public int nthUglyNumber(int n) { 7 // write your code here 8 Queue<Long> queue = new PriorityQueue<>(); 9 Set<Long> set = new HashSet<>(); 10 int[] factors = new int[3]; 11 12 factors[0] = 2; 13 factors[1] = 3; 14 factors[2] = 5; 15 queue.add(1L); 16 Long number = 0L; 17 for (int i = 0; i < n; i++) { 18 number = queue.poll(); 19 for (int j = 0; j < 3; j++) { 20 if (!set.contains(number * factors[j])) { 21 queue.add(number * factors[j]); 22 set.add(number * factors[j]); 23 } 24 } 25 } 26 return number.intValue(); 27 } 28 }
method2: 丑数一定是某一个丑数*2或者*3或者*5的结果,维护三个指针,例如如果该指针*2结果大于上一个丑数,指针+1


1 public class Solution { 2 /** 3 * @param n: An integer 4 * @return: the nth prime number as description. 5 */ 6 public int nthUglyNumber(int n) { 7 // write your code here 8 List<Integer> res = new ArrayList<>(); 9 res.add(1); 10 int p2 = 0; 11 int p3 = 0; 12 int p5 = 0; 13 for (int i = 1; i < n; i++) { 14 int lastNum = res.get(res.size() - 1); 15 while (res.get(p2) * 2 <= lastNum) p2++; 16 while (res.get(p3) * 3 <= lastNum) p3++; 17 while (res.get(p5) * 5 <= lastNum) p5++; 18 res.add(Math.min(Math.min(res.get(p2) * 2, res.get(p3) * 3), res.get(p5) * 5)); 19 } 20 21 return res.get(n - 1); 22 } 23 }
545. Top k Largest Numbers II


1 public class Solution { 2 private int maxSize; 3 private Queue<Integer> minHeap; 4 5 /* 6 * @param k: An integer 7 */ 8 public Solution(int k) { 9 // do intialization if necessary 10 this.maxSize = k; 11 this.minHeap = new PriorityQueue<>(); 12 } 13 14 /* 15 * @param num: Number to be added 16 * @return: nothing 17 */ 18 public void add(int num) { 19 // write your code here 20 if (minHeap.size() < maxSize) { 21 minHeap.offer(num); 22 return; 23 } 24 if (num > minHeap.peek()) { 25 minHeap.poll(); 26 minHeap.offer(num); 27 } 28 } 29 30 /* 31 * @return: Top k element 32 */ 33 public List<Integer> topk() { 34 // write your code here 35 List<Integer> res = new ArrayList<>(); 36 for (Integer num : minHeap) { 37 res.add(num); 38 } 39 Collections.sort(res); 40 Collections.reverse(res); 41 return res; 42 } 43 }
104. Merge K Sorted Lists
method1:利用最小堆


1 /** 2 * Definition for ListNode. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int val) { 7 * this.val = val; 8 * this.next = null; 9 * } 10 * } 11 */ 12 public class Solution { 13 14 private Comparator<ListNode> listNodeComparator = new Comparator<ListNode>() { 15 @Override 16 public int compare(ListNode o1, ListNode o2) { 17 return (o1.val - o2.val); 18 } 19 }; 20 21 /** 22 * @param lists: a list of ListNode 23 * @return: The head of one sorted list. 24 */ 25 public ListNode mergeKLists(List<ListNode> lists) { 26 // write your code here 27 if (lists == null || lists.size() == 0) { 28 return null; 29 } 30 31 Queue<ListNode> minheap = new PriorityQueue<>(lists.size(), listNodeComparator); 32 for (ListNode node : lists) { 33 if(node != null){ 34 minheap.add(node); 35 } 36 } 37 38 ListNode dummy = new ListNode(0); 39 ListNode tail = dummy; 40 while (!minheap.isEmpty()) { 41 ListNode head = minheap.poll(); 42 tail.next = head; 43 tail = head; 44 if (head.next != null) { 45 minheap.add(head.next); 46 } 47 } 48 return dummy.next; 49 } 50 }
method2: merge 2 by 2(待二刷)
method3: 分治(待二刷)
613. High Five


1 /** 2 * Definition for a Record 3 * class Record { 4 * public int id, score; 5 * public Record(int id, int score){ 6 * this.id = id; 7 * this.score = score; 8 * } 9 * } 10 */ 11 public class Solution { 12 /** 13 * @param results a list of <student_id, score> 14 * @return find the average of 5 highest scores for each person 15 * Map<Integer, Double> (student_id, average_score) 16 */ 17 public Map<Integer, Double> highFive(Record[] results) { 18 // Write your code here 19 Map<Integer, Double> resMap = new HashMap<>(); 20 if (results == null || results.length == 0) { 21 return resMap; 22 } 23 Map<Integer, PriorityQueue<Integer>> scoreMap = new HashMap<>(); 24 for (Record record : results) { 25 if (!scoreMap.containsKey(record.id)) { 26 scoreMap.put(record.id, new PriorityQueue<Integer>()); 27 } 28 29 PriorityQueue<Integer> heap = scoreMap.get(record.id); 30 if (heap.size() < 5) { 31 heap.add(record.score); 32 continue; 33 } 34 35 if (record.score > heap.peek()) { 36 heap.poll(); 37 heap.add(record.score); 38 } 39 } 40 41 for (Map.Entry<Integer, PriorityQueue<Integer>> entry : scoreMap.entrySet()) { 42 PriorityQueue<Integer> scoreHeap = entry.getValue(); 43 int sum = 0; 44 while (!scoreHeap.isEmpty()) { 45 sum += scoreHeap.poll(); 46 } 47 double ave = sum / 5.0; 48 resMap.put(entry.getKey(), ave); 49 } 50 51 return resMap; 52 53 } 54 }
612. K Closest Points


1 public class Solution { 2 /** 3 * @param points: a list of points 4 * @param origin: a point 5 * @param k: An integer 6 * @return: the k closest points 7 */ 8 public Point[] kClosest(Point[] points, Point origin, int k) { 9 // write your code here 10 if (points == null || points.length < k || k == 0) { 11 return null; 12 } 13 14 Comparator<Point> comparator = new Comparator<Point>() { 15 @Override 16 public int compare(Point o1, Point o2) { 17 return compareDistance(o2, o1, origin); 18 } 19 }; 20 Point[] res = new Point[k]; 21 PriorityQueue<Point> maxHeap = new PriorityQueue<>(comparator); 22 for (Point point : points) { 23 if (maxHeap.size() < k) { 24 maxHeap.add(point); 25 continue; 26 } 27 if (compareDistance(point, maxHeap.peek(), origin) < 0) { 28 maxHeap.poll(); 29 maxHeap.add(point); 30 } 31 } 32 33 for (int i = k - 1; i >= 0; i--) { 34 res[i] = maxHeap.poll(); 35 } 36 return res; 37 } 38 39 private int compareDistance(Point o1, Point o2, Point center) { 40 int distance1 = (o1.x - center.x) * (o1.x - center.x) + (o1.y - center.y) * (o1.y - center.y); 41 int distance2 = (o2.x - center.x) * (o2.x - center.x) + (o2.y - center.y) * (o2.y - center.y); 42 if (distance1 == distance2) { 43 return o1.x != o2.x ? o1.x - o2.x : o1.y - o2.y; 44 } 45 return distance1 - distance2; 46 } 47 }
81. Find Median from Data Stream


1 public class Solution { 2 /** 3 * @param nums: A list of integers 4 * @return: the median of numbers 5 */ 6 7 //此题中位数定义和一般的有区别,写的时候需要注意 8 //存储后半部分的数据 9 private PriorityQueue<Integer> minHeap; 10 //存储前半部分的数据 11 private PriorityQueue<Integer> maxHeap; 12 private int count;//已加入的数 13 14 public int[] medianII(int[] nums) { 15 // write your code here 16 if (nums == null || nums.length == 0) { 17 return null; 18 } 19 int len = nums.length; 20 int[] res = new int[len]; 21 Comparator<Integer> maxComparator = new Comparator<Integer>() { 22 @Override 23 public int compare(Integer o1, Integer o2) { 24 return o2.compareTo(o1); 25 } 26 }; 27 minHeap = new PriorityQueue<>(len); 28 maxHeap = new PriorityQueue<>(len, maxComparator); 29 for (int i = 0; i < len; i++) { 30 addNumber(nums[i]); 31 res[i] = getMedian(); 32 } 33 34 return res; 35 } 36 37 public void addNumber(int num) { 38 maxHeap.add(num); 39 count++; 40 //总是先add前半部分数,保证maxHeap.size()>=minHeap.size() 41 if (count % 2 == 1) { 42 if (minHeap.isEmpty()) { 43 return; 44 } 45 46 //交换堆顶,保证有序 47 if (maxHeap.peek() > minHeap.peek()) { 48 int maxPeek = maxHeap.poll(); 49 int minPeek = minHeap.poll(); 50 minHeap.add(maxPeek); 51 maxHeap.add(minPeek); 52 } 53 54 return; 55 } 56 //当count为奇数时,maxHeap.size-minHeap.size=1,因而当count变为偶数时,只用无脑再将peek取出添到后半部分 57 minHeap.add(maxHeap.poll()); 58 return; 59 } 60 61 public int getMedian() { 62 return maxHeap.peek(); 63 } 64 }
401. Kth Smallest Number in Sorted Matrix
此题注意应该维护的是最小堆,很容易误判成最大堆


1 class Pair { 2 private int x; 3 private int y; 4 private int val; 5 6 public Pair(int x, int y, int val) { 7 this.x = x; 8 this.y = y; 9 this.val = val; 10 } 11 12 public int getX() { 13 return x; 14 } 15 16 public void setX(int x) { 17 this.x = x; 18 } 19 20 public int getY() { 21 return y; 22 } 23 24 public void setY(int y) { 25 this.y = y; 26 } 27 28 public int getVal() { 29 return val; 30 } 31 32 public void setVal(int val) { 33 this.val = val; 34 } 35 } 36 37 public class Solution { 38 /** 39 * @param matrix: a matrix of integers 40 * @param k: An integer 41 * @return: the kth smallest number in the matrix 42 */ 43 public int kthSmallest(int[][] matrix, int k) { 44 // write your code here 45 if (matrix == null || matrix.length == 0 || matrix.length * matrix[0].length < k) { 46 return -1; 47 } 48 Comparator<Pair> comparator = new Comparator<Pair>() { 49 @Override 50 public int compare(Pair o1, Pair o2) { 51 return o1.getVal() - o2.getVal(); 52 } 53 }; 54 int r = matrix.length; 55 int c = matrix[0].length; 56 PriorityQueue<Pair> minHeap = new PriorityQueue<>(comparator); 57 boolean[][] visited = new boolean[r][c]; 58 59 minHeap.add(new Pair(0, 0, matrix[0][0])); 60 visited[0][0] = true; 61 62 for (int i = 1; i <= k - 1; i++) { 63 Pair cur = minHeap.poll(); 64 if (cur.getX() + 1 < r && !visited[cur.getX() + 1][cur.getY()]) { 65 minHeap.add(new Pair(cur.getX() + 1, cur.getY(), matrix[cur.getX() + 1][cur.getY()])); 66 visited[cur.getX() + 1][cur.getY()] = true; 67 } 68 if (cur.getY() + 1 < c && !visited[cur.getX()][cur.getY() + 1]) { 69 minHeap.add(new Pair(cur.getX(), cur.getY() + 1, matrix[cur.getX()][cur.getY() + 1])); 70 visited[cur.getX()][cur.getY() + 1] = true; 71 } 72 } 73 74 return minHeap.peek().getVal(); 75 } 76 }