手写 skip list,看看自己最近有多脑残

This commit is contained in:
YunaiV
2019-06-22 08:34:38 +08:00
parent c06797884e
commit 0bc9e92a23
12 changed files with 801 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0001;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
class Solution {
// public int[] twoSum(int[] nums, int target) {
// for (int i = 0; i < nums.length; i++) {
// for (int j = i + 1; j < nums.length; j++) {
// int sum = nums[i] + nums[j];
// if (sum == target) {
// return new int[]{i, j};
// }
// }
// }
// return new int[]{0};
// }
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> numMap = new HashMap<>(nums.length, 1.0F);
for (int i = 0; i < nums.length; i++) {
// 避免相同数字相加,恰好相等
Integer j = numMap.get(target - nums[i]);
if (j != null) {
return new int[]{j, i};
}
numMap.put(nums[i], i);
}
return new int[]{0};
}
public static void main(String[] args) {
// int[] result = new Solution().twoSum(new int[]{0, 4, 3, 0}, 0);
// System.out.println(Arrays.toString(result));
int[] result = new Solution().twoSum(new int[]{2, 7, 11, 15}, 9);
System.out.println(Arrays.toString(result));
// int[] result = new Solution().twoSum(new int[]{-1, -2, -3, -4, -5}, -8);
// System.out.println(Arrays.toString(result));
}
}

View File

@@ -0,0 +1,107 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0015;
import java.util.*;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
// 排序
Arrays.sort(nums);
// 获得结果
List<List<Integer>> results = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
int target = -nums[i];
// 遍历
int start = i + 1, end = nums.length - 1;
while (start < end) {
// 符合条件
int sum = nums[start] + nums[end];
if (sum == target) {
// 添加到结果
results.add(Arrays.asList(nums[i], nums[start], nums[end]));
// 增大 start
do {
start++;
} while (nums[start] == nums[start - 1] && start < end);
// 减小 end
do {
end--;
} while (nums[end] == nums[end + 1] && start < end);
continue;
}
// 小于预期,说明 start 对应的值太小start 继续前进。
if (sum < target) {
do {
start++;
} while (nums[start] == nums[start - 1] && start < end);
// 大于预期,说明 end 对应的值太大end 继续后退
} else {
do {
end--;
} while (nums[end] == nums[end + 1] && start < end);
}
}
}
return results;
}
public List<List<Integer>> convert(Set<List<Integer>> result) {
List<List<Integer>> newResult = new ArrayList<>(result.size());
newResult.addAll(result);
return newResult;
}
private List<List<Integer>> removeSome(List<List<Integer>> results) {
// 排序
for (List<Integer> result : results) {
Collections.sort(result);
}
// 移除重复的
List<List<Integer>> newResults = new ArrayList<>();
for (List<Integer> result : results) {
boolean exists = false;
for (List<Integer> targetResult : newResults) {
if (targetResult.equals(result)) {
exists = true;
break;
}
}
if (!exists) {
newResults.add(result);
}
}
return newResults;
}
// public int[] twoSum(int[] nums, int start, int target) {
// Map<Integer, Integer> numMap = new HashMap<>(nums.length, 1.0F);
// for (int i = start; i < nums.length; i++) {
// numMap.put(nums[i], i);
// }
// for (int i = start; i < nums.length; i++) {
// // 避免相同数字相加,恰好相等
// Integer j = numMap.get(target - nums[i]);
// if (j != null) {
// if (j == i) {
// continue;
// }
// return new int[]{i, j};
// }
// }
// return new int[]{0};
// }
public static void main(String[] args) {
// System.out.println(new Solution().threeSum(new int[]{-1, 0, 1, 2, -1, -4}));
// System.out.println(new Solution().threeSum(new int[]{0,0,0,0}));
// System.out.println(new Solution().threeSum(new int[]{-2, 0, 1, 1, 2}));
System.out.println(new Solution().threeSum(new int[]{1,-1,-1,0}));
// System.out.println(new Solution().threeSum(new int[]{-7,-11,12,-15,14,4,4,11,-11,2,-8,5,8,14,0,3,2,3,-3,-15,-2,3,6,1,2,8,-5,-7,3,1,8,11,-3,6,3,-4,-13,-15,14,-8,2,-8,4,-13,13,11,5,0,0,9,-8,5,-2,14,-9,-15,-1,-6,-15,9,10,9,-2,-8,-8,-14,-5,-14,-14,-6,-15,-5,-7,5,-11,14,-7,2,-9,0,-4,-1,-9,9,-10,-11,1,-4,-2,2,-9,-15,-12,-4,-8,-5,-11,-6,-4,-9,-4,-3,-7,4,9,-2,-5,-13,7,2,-5,-12,-14,1,13,-9,-3,-9,2,3,8,0,3}));
}
}

View File

@@ -0,0 +1,43 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0020;
import java.util.ArrayList;
import java.util.List;
public class Solution {
public boolean isValid(String s) {
List<Character> array = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '('
|| ch == '{'
|| ch == '[') {
array.add(ch);
} else {
if (array.isEmpty()) {
return false;
}
int arrayCh = array.get(array.size() - 1);
if ((arrayCh == '(' && ch == ')')
|| (arrayCh == '{' && ch == '}')
|| (arrayCh == '[' && ch == ']')) {
array.remove(array.size() - 1);
} else {
return false;
}
}
}
return array.isEmpty();
}
public static void main(String[] args) {
System.out.println(new Solution().isValid("()"));
System.out.println(new Solution().isValid("()[]{}"));
System.out.println(new Solution().isValid("(]"));
System.out.println(new Solution().isValid("([)]"));
System.out.println(new Solution().isValid("{[]}"));
System.out.println(new Solution().isValid("["));
System.out.println(new Solution().isValid("]"));
}
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0025;
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
@Override
public String toString() {
return "ListNode{" +
"val=" + val +
'}';
}
}

View File

@@ -0,0 +1,93 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0025;
class Solution {
private ListNode swap(ListNode first, ListNode head, ListNode last) {
ListNode originCurrent = head;
// 先设置 first 指向 last
// if (first != null) {
// first.next = last;
// }
// 进行反序
ListNode newHead = null;
ListNode tail = last.next; // 用于判断结尾
while (head != tail) {
ListNode current = head;
head = head.next;
// 反向指向
current.next = newHead;
newHead = current;
}
// 原始的头,指向 tail
originCurrent.next = tail;
// first 指向新的头
if (first != null) {
first.next = newHead;
}
// 返回结果
return newHead;
}
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null) {
return null;
}
ListNode tmp = head;
ListNode first = null; // 记录每个 N 个一组的前一个节点。
ListNode current = head; // 记录 N 组的头节点。
ListNode newHead = null; // 因为反转,所以可能产生新的头
int counts = 0; // 计数 N
while (tmp != null) {
// 每 N 个形成一组,进行交换。
counts++;
if (counts == k) {
ListNode tail = tmp.next;
ListNode result = swap(first, current, tmp);
if (newHead == null) { // 第一次反转的结果,成为新的头。
newHead = result;
}
counts = 0;
// 设置下一组
first = current;
current = tail;
tmp = tail;
} else {
// 跳到下一个节点
tmp = tmp.next;
}
}
return newHead != null ? newHead : head;
}
public static void main(String[] args) {
if (false) {
ListNode head = new ListNode(1);
int[] values = new int[]{2, 3, 4, 5};
ListNode current = head;
for (int value : values) {
current.next = new ListNode(value);
current = current.next;
}
ListNode result = new Solution().reverseKGroup(head, 3);
System.out.println(result);
}
if (true) {
ListNode head = new ListNode(1);
int[] values = new int[]{2, 3, 4};
ListNode current = head;
for (int value : values) {
current.next = new ListNode(value);
current = current.next;
}
ListNode result = new Solution().reverseKGroup(head, 2);
System.out.println(result);
}
}
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0142;
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
@Override
public String toString() {
return "ListNode{" +
"val=" + val +
'}';
}
}

View File

@@ -0,0 +1,135 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0142;
import java.util.HashSet;
import java.util.Set;
public class Solution {
/**
* 性能较差
*
* 每次走到下一个节点,都从头节点重新遍历,看看有没回环。
*
* @param head 头节点
* @return 回环的点
*/
public ListNode detectCycle01(ListNode head) {
if (head == null) {
return null;
}
// 寻找结尾
ListNode current = head;
while (current.next != null) {
ListNode oldCurrent = current;
ListNode tmpHead = head;
// 跳到下一个
current = current.next;
// 处理,自己指向自己的情况
if (current == oldCurrent) {
return current;
}
// 从头结点开始走,判断是否有回环
while (tmpHead != null) {
//
if (tmpHead == oldCurrent) {
break;
}
if (tmpHead == current) {
return current;
}
tmpHead = tmpHead.next;
}
}
return null;
}
public ListNode detectCycle02(ListNode head) {
if (head == null) {
return null;
}
Set<ListNode> visited = new HashSet<>();
while (head != null && head.next != null) {
visited.add(head);
if (visited.contains(head.next)) {
return head.next;
}
head = head.next;
}
return null;
}
private ListNode getIntersect(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
return slow;
}
}
return null;
}
public ListNode detectCycle03(ListNode head) {
if (head == null) {
return null;
}
// 先使用快慢指针,找到想交的节点
ListNode intersect = getIntersect(head);
if (intersect == null) { // 如果为空,说明不存在环
return null;
}
// 找到环的入口
ListNode ptr1 = head;
ListNode ptr2 = intersect;
while (ptr1 != ptr2) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
return ptr1;
}
public ListNode detectCycle(ListNode head) {
// return detectCycle01(head);
// return detectCycle02(head);
return detectCycle03(head);
}
public static void main(String[] args) {
if (true) {
ListNode head = new ListNode(1);
ListNode tail = new ListNode(2);
head.next = tail;
tail.next = head;
System.out.println(new Solution().detectCycle(head));
}
if (false) {
ListNode head = new ListNode(1);
head.next = head;
System.out.println(new Solution().detectCycle(head));
}
if (false) {
ListNode head = new ListNode(1);
ListNode tail = new ListNode(2);
head.next = tail;
tail.next = tail;
System.out.println(new Solution().detectCycle(head));
}
if (false) {
ListNode head = new ListNode(1);
ListNode tail = new ListNode(2);
ListNode second = new ListNode(3);
head.next = second;
second.next = tail;
tail.next = second;
ListNode result = new Solution().detectCycle(head);
// System.out.println();
assert result == second;
}
}
}

View File

@@ -0,0 +1,45 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0242;
import java.util.HashMap;
import java.util.Map;
class Solution {
public boolean isAnagram(String s, String t) {
if (s == null || t == null) {
return false;
}
if (s.length() != t.length()) {
return false;
}
// 创建 s 使用的哈希表
Map<Character, Integer> map = new HashMap<>();
for (char ch : s.toCharArray()) {
Integer counts = map.get(ch);
counts = counts != null ? counts + 1 : 1;
map.put(ch, counts);
}
// 判断 t 是否有
for (char ch : t.toCharArray()) {
Integer counts = map.get(ch);
if (counts == null) {
return false;
}
counts--;
if (counts == 0) {
map.remove(ch);
} else {
map.put(ch, counts);
}
}
return true;
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.isAnagram("anagram", "nagaram"));
System.out.println(solution.isAnagram("rat", "cat"));
System.out.println(solution.isAnagram("ccac", "aacc"));
}
}

View File

@@ -0,0 +1,104 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no039;
import java.util.*;
public class Solution {
class Node {
public int index;
public int value;
public Node(int index, int value) {
this.index = index;
this.value = value;
}
}
public int[] maxSlidingWindow(int[] nums, int k) {
List<Node> queue = new LinkedList<>();
List<Integer> result = new ArrayList<>(nums.length - k + 1);
for (int i = 0; i < nums.length; i++) {
int maxValue = Integer.MIN_VALUE;
if (!queue.isEmpty()) {
// 移除超过范围的节点
if (queue.get(0).index == i - k) {
queue.remove(0);
}
// 移除队列中,小于当前位置的元素
ListIterator<Node> listiterator = queue.listIterator(queue.size()); // 倒序向前
while (listiterator.hasPrevious()) {
Node node = listiterator.previous();
if (nums[i] >= node.value) {
listiterator.remove();
} else {
maxValue = node.value; // 说明,此值更大
}
}
}
// 判断是否有更大的
if (nums[i] > maxValue) {
maxValue = nums[i];
}
// 添加到队尾
queue.add(new Node(i, nums[i]));
// 添加到结果
if (i >= k -1) {
result.add(maxValue);
}
}
return result.stream().mapToInt(i -> i).toArray();
}
// public int[] maxSlidingWindow(int[] nums, int k) {
// int[] num = nums;
// int size = k;
// //num就是numssize就是kres一开始也可以用数组
// ArrayList<Integer> res = new ArrayList<>();
// if(num == null || num.length == 0 || size <= 0 || size > num.length){
// return res.stream().mapToInt(i -> i).toArray();
// }
// int left = 0, right = 0, max = num[0];
// while(right < num.length){
// while(right < num.length-1 && right - left < size-1){
// right++;
// if(num[right] > max){
// max = num[right];
// }
// }
// res.add(max);
// left++;
// if(right == num.length-1) break;
// if(num[left-1] == max){
// right = left;
// max = num[left];
// }
// }
// return res.stream().mapToInt(i -> i).toArray();
// }
public static void main(String[] args) {
if (false) {
int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
int k = 3;
int[] result = new Solution().maxSlidingWindow(nums, k);
System.out.println(Arrays.toString(result));
}
if (true) {
int[] nums = {1, 3, 1, 2, 0, 5};
int k = 3;
int[] result = new Solution().maxSlidingWindow(nums, k);
System.out.println(Arrays.toString(result));
}
}
// private static void println(List<Node> queue) {
// for (Node node : queue) {
// System.out.print(" " + node.value);
// }
// System.out.println();
// }
}

View File

@@ -0,0 +1,136 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0703;
class KthLargest {
/**
* 小顶堆
*/
private int[] heap;
/**
* 堆的位置
*/
private int heapIndex;
private int k;
public KthLargest(int k, int[] nums) {
this.heap = new int[k + 1];
this.heapIndex = 1;
this.k = k;
// 初始化
for (int num : nums) {
add(num);
}
}
public int add(int val) {
if (heapIndex <= k) {
// 赋值
heap[heapIndex] = val;
heapIndex++;
// 向上堆化
heapifyUp(heapIndex - 1);
} else {
if (val > heap[1]) { // 大于最小值,才有资格加入其中。因为我们构建的 heap 是小顶堆,最上面存储的是第 k 大。
// 赋值
heap[1] = val;
heapifyDown(1);
}
}
return heap[1];
}
// private int remove0() {
// // 取头元素
// int val = heap[1];
//
// // 将尾巴设置到头
// heap[1] = heap[heapIndex - 1];
// heapIndex--;
//
// // 向下堆化
// heapifyDown(1);
//
// return val;
// }
public void heapifyUp(int index) {
while (index > 1) { // 注意,此处要大于 1
int parent = index / 2;
if (heap[index] < heap[parent]) {
swap(index, parent);
index = parent;
} else {
break;
}
}
}
private void heapifyDown(int index) {
while (true) {
int pos = index;
// 求子节点中,哪个
if (index * 2 < heapIndex && heap[index * 2] < heap[index]) {
pos = index * 2;
}
if (index * 2 + 1 < heapIndex && heap[index * 2 + 1] < heap[pos]) {
pos = index * 2 + 1;
}
// 如果毫无变化,说明已经不需要继续向下
if (pos == index) {
return;
}
// 交换
swap(index, pos);
index = pos;
}
}
private void swap(int i, int j) {
int tmp = heap[i];
heap[i] = heap[j];
heap[j] = tmp;
}
// private int findMaxValueIndex() {
// int max = Integer.MIN_VALUE;
// int maxIndex = -1;
// for (int i = log2(heapIndex) * 2; i < heapIndex; i++) { // 从 log2(heapIndex) * 2 的原因是,从叶子节点开始。因为我们构建的是小顶堆,那么最大值必定在叶子节点上。
// if (heap[i] > max) {
// max = heap[i];
// maxIndex = i;
// }
// }
// return maxIndex;
// }
//
// private static int log2(int x) {
// return (int) (Math.log(x) / Math.log(2));
// }
public static void main(String[] args) {
if (false) {
int k = 3;
int[] nums = {4, 5, 8, 2};
KthLargest kthLargest = new KthLargest(k, nums);
System.out.println(kthLargest.add(3));
System.out.println(kthLargest.add(5));
System.out.println(kthLargest.add(10));
System.out.println(kthLargest.add(9));
System.out.println(kthLargest.add(4));
}
if (true) {
int k = 1;
int[] nums = {};
KthLargest kthLargest = new KthLargest(k, nums);
System.out.println(kthLargest.add(-3));
System.out.println(kthLargest.add(-2));
System.out.println(kthLargest.add(-4));
System.out.println(kthLargest.add(0));
System.out.println(kthLargest.add(4));
}
}
}

View File

@@ -0,0 +1,57 @@
package cn.iocoder.springboot.labs.lab09.leetcode.no0703;
import java.util.PriorityQueue;
import java.util.Queue;
class KthLargest2 {
private Queue<Integer> queue;
private int k;
public KthLargest2(int k, int[] nums) {
queue = new PriorityQueue<>(k);
this.k = k;
// 初始化
for (int num : nums) {
add(num);
}
}
public int add(int val) {
if (queue.size() < k) {
// 赋值
queue.add(val);
} else {
if (val > queue.peek()) { // 大于最小值,才有资格加入其中。因为我们构建的 heap 是小顶堆,最上面存储的是第 k 大。
queue.poll();
queue.add(val);
}
}
return queue.peek();
}
public static void main(String[] args) {
if (true) {
int k = 3;
int[] nums = {4, 5, 8, 2};
KthLargest2 kthLargest = new KthLargest2(k, nums);
System.out.println(kthLargest.add(3));
System.out.println(kthLargest.add(5));
System.out.println(kthLargest.add(10));
System.out.println(kthLargest.add(9));
System.out.println(kthLargest.add(4));
}
if (false) {
int k = 1;
int[] nums = {};
KthLargest2 kthLargest = new KthLargest2(k, nums);
System.out.println(kthLargest.add(-3));
System.out.println(kthLargest.add(-2));
System.out.println(kthLargest.add(-4));
System.out.println(kthLargest.add(0));
System.out.println(kthLargest.add(4));
}
}
}

View File

@@ -0,0 +1,4 @@
/**
* leetcode 题目解答
*/
package cn.iocoder.springboot.labs.lab09.leetcode;