From 486f4ed13be25a7319063b86ed0ea0866b7aaac3 Mon Sep 17 00:00:00 2001 From: Leo <582717189@qq.com> Date: Wed, 23 Dec 2020 18:41:08 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=83=E4=B9=A0,=E7=AC=AC15=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/leo/class01_01/BSAwesome.java | 29 ++- src/leo/class01_01/BSExist.java | 21 +- src/leo/class01_01/BSNear.java | 44 +++- src/leo/class01_01/BubbleSort.java | 15 +- src/leo/class01_01/InsertionSort.java | 24 +- src/leo/class01_01/SelectionSort.java | 16 +- src/leo/class01_02/EvenTimesOddTimes.java | 30 ++- src/leo/class01_02/KM.java | 40 +++- src/leo/class02_03/DeleteGivenValue.java | 81 ++++++- src/leo/class02_03/GetMax.java | 18 +- src/leo/class02_03/GetMinStack.java | 82 ++++++- src/leo/class02_03/LinkedList.java | 17 +- src/leo/class02_03/RingArray.java | 41 +++- src/leo/class02_03/StackAndQueue.java | 118 +++++++++- src/leo/class09_14/BestArrange.java | 170 ++++++++++++++ src/leo/class09_14/IPO.java | 75 ++++++ src/leo/class09_14/LessMoneySplitGold.java | 119 ++++++++++ src/leo/class09_14/Light.java | 103 +++++++++ src/leo/class09_14/UnionFindClass.java | 83 +++++++ src/leo/class09_15/FriendCircles.java | 79 +++++++ src/leo/class09_15/NumberOfIslands.java | 257 +++++++++++++++++++++ 21 files changed, 1443 insertions(+), 19 deletions(-) create mode 100644 src/leo/class09_14/BestArrange.java create mode 100644 src/leo/class09_14/IPO.java create mode 100644 src/leo/class09_14/LessMoneySplitGold.java create mode 100644 src/leo/class09_14/Light.java create mode 100644 src/leo/class09_14/UnionFindClass.java create mode 100644 src/leo/class09_15/FriendCircles.java create mode 100644 src/leo/class09_15/NumberOfIslands.java diff --git a/src/leo/class01_01/BSAwesome.java b/src/leo/class01_01/BSAwesome.java index 9cce675..1967cf0 100644 --- a/src/leo/class01_01/BSAwesome.java +++ b/src/leo/class01_01/BSAwesome.java @@ -2,6 +2,8 @@ package leo.class01_01; import leo.util.ArrayUtil; +import java.util.function.IntPredicate; + /** * @author Leo * @ClassName BSAwesome @@ -266,6 +268,31 @@ public class BSAwesome { return -1; } + public static int BSAwesome8(int[] arr) { + if (arr.length == 0 || arr == null) { + return -1; + } + if (arr.length == 1 || arr[0] < arr[1]) { + return 0; + } + if (arr[arr.length - 1] < arr[arr.length - 2]) { + return arr.length - 1; + } + int l = 0; + int r = arr.length - 1; + while (l <= r) { + int m = l + ((r - l) >> 1); + if (arr[m] > arr[m + 1]) { + l = m + 1; + } else if (arr[m] > arr[m - 1]) { + r = m - 1; + } else { + return m; + } + } + return -1; + } + public static int verifyBSAwesome(int[] arr, int index) { if (arr.length == 0 || index == -1) { return -1; @@ -303,7 +330,7 @@ public class BSAwesome { boolean succeed = true; for (int i = 0; i < testTime; i++) { int[] arr = ArrayUtil.randomAdjacentNotEqualArray(maxSize, range); - final int index = BSAwesome7(arr); + final int index = BSAwesome8(arr); final int verifyIndex = verifyBSAwesome(arr,index); if (index != verifyIndex) { succeed = false; diff --git a/src/leo/class01_01/BSExist.java b/src/leo/class01_01/BSExist.java index ff9a727..b6c0e60 100644 --- a/src/leo/class01_01/BSExist.java +++ b/src/leo/class01_01/BSExist.java @@ -209,6 +209,25 @@ public class BSExist { return arr[l] == value; } + public static boolean exist10(int[] arr, int value) { + if (arr.length == 0 || arr == null) { + return false; + } + int l = 0; + int r = arr.length - 1; + while (l < r) { + int m = l + ((r - l) >> 1); + if (arr[m] == value) { + return true; + } else if (arr[m] > value) { + r = m - 1; + } else if (arr[m] < value) { + l = m + 1; + } + } + return arr[l] == value; + } + /** * 功能描述 : test * @author Leo @@ -237,7 +256,7 @@ public class BSExist { int[] sortArr = ArrayUtil.randomSortArray(maxSize, range); int value = (int) ((range + 1) * Math.random() - (range + 1) * Math.random()); - if (exist9(sortArr, value) != exist(sortArr, value)) { + if (exist10(sortArr, value) != exist(sortArr, value)) { succeed = false; ArrayUtil.printArr(sortArr); break; diff --git a/src/leo/class01_01/BSNear.java b/src/leo/class01_01/BSNear.java index 88a0777..4a4c685 100644 --- a/src/leo/class01_01/BSNear.java +++ b/src/leo/class01_01/BSNear.java @@ -1,5 +1,6 @@ package leo.class01_01; +import jdk.nashorn.internal.ir.IfNode; import leo.util.ArrayUtil; import java.util.Arrays; @@ -250,6 +251,24 @@ public class BSNear { return index; } + public static int BsNearLeft12(int[] arr, int value) { + if (arr.length == 0 || arr == null) { + return -1; + } + int l = 0; + int r = arr.length - 1; + int index = -1; + while (l <= r) { + int m = l + ((r - l) >> 1); + if (arr[m] >= value) { + index = m; + r = m - 1; + }else{ + l = m + 1; + } + } + return index; + } /** @@ -473,6 +492,25 @@ public class BSNear { return index; } + public static int BSNearRight10(int[] arr, int value) { + if (arr == null || arr.length == 0) { + return -1; + } + int index = -1; + int l = 0; + int r = arr.length - 1; + while (l <= r) { + int m = l + ((r - l) >> 1); + if (arr[m] <= value) { + index = m; + l = m + 1; + }else{ + r = m - 1; + } + } + return index; + } + public static int forTestBSNearRight(int[] arr, int value) { int index = -1; @@ -496,7 +534,7 @@ public class BSNear { for (int i = 0; i < testTime; i++) { int[] sortArr = randomArray(maxSize, range); int value = (int) ((range + 1) * Math.random() - (range + 1) * Math.random()); - int res1 = BSNearLeft10(sortArr, value); + int res1 = BsNearLeft12(sortArr, value); int res2 = forTestBSNearLeft(sortArr, value); if (res1 != res2) { success = false; @@ -506,7 +544,7 @@ public class BSNear { break; } - /*int res3 = BSNearRight9(sortArr, value); + int res3 = BSNearRight10(sortArr, value); int res4 = forTestBSNearRight(sortArr, value); if (res3 != res4) { success = false; @@ -514,7 +552,7 @@ public class BSNear { System.out.println("BSNearRight=" + res3); System.out.println("forTestBSNearRight=" + res4); break; - }*/ + } } System.out.println(success ? "Nice!!" : "Fucking Fucked!"); } diff --git a/src/leo/class01_01/BubbleSort.java b/src/leo/class01_01/BubbleSort.java index df42f8f..f52d85f 100644 --- a/src/leo/class01_01/BubbleSort.java +++ b/src/leo/class01_01/BubbleSort.java @@ -181,6 +181,19 @@ public class BubbleSort { } } + public static void bubbleSort13(int[] arr) { + if (arr.length < 2 || arr == null) { + return; + } + for (int i = arr.length - 1; i >= 0; i--) { + for (int j = 0; j < i; j++) { + if (arr[j] > arr[i]) { + swap(arr, j, i); + } + } + } + + } /** * 功能描述 : 交换 @@ -212,7 +225,7 @@ public class BubbleSort { for (int i = 0; i < testOfTime; i++) { int[] arr = ArrayUtil.randomArray(maxSize, range); int[] anotherArr = ArrayUtil.copyArray(arr); - bubbleSort12(arr); + bubbleSort13(arr); Arrays.sort(anotherArr); if (!ArrayUtil.isEqual(arr, anotherArr)) { succeed = false; diff --git a/src/leo/class01_01/InsertionSort.java b/src/leo/class01_01/InsertionSort.java index 79b704e..4fe37f0 100644 --- a/src/leo/class01_01/InsertionSort.java +++ b/src/leo/class01_01/InsertionSort.java @@ -197,6 +197,28 @@ public class InsertionSort { } } + public static void insertionSort15(int[] arr) { + if (arr.length < 2 || arr == null) { + return; + } + for (int i = 1; i < arr.length; i++) { + for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { + swap(arr, j, j + 1); + } + } + } + + public static void insertionSort16(int[] arr) { + if (arr.length < 2 || arr == null) { + return; + } + for (int i = 1; i < arr.length; i++) { + for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { + swap(arr, j, j + 1); + } + } + } + private static void swap(int[] arr, int i, int j) { if (arr == null || arr.length < 2 @@ -221,7 +243,7 @@ public class InsertionSort { for (int i = 0; i < testOfTime; i++) { int[] arr = ArrayUtil.randomArray(maxSize, range); int[] anotherArr = ArrayUtil.copyArray(arr); - insertionSort14(arr); + insertionSort16(arr); Arrays.sort(anotherArr); if (!ArrayUtil.isEqual(arr, anotherArr)) { succeed = false; diff --git a/src/leo/class01_01/SelectionSort.java b/src/leo/class01_01/SelectionSort.java index 22b5f11..883b80c 100644 --- a/src/leo/class01_01/SelectionSort.java +++ b/src/leo/class01_01/SelectionSort.java @@ -190,6 +190,20 @@ public class SelectionSort { } } + public static void selectionSort13(int[] arr) { + if (arr.length < 2 || arr == null) { + return; + } + for (int i = 0; i < arr.length; i++) { + int l = i; + for (int j = i + 1; j < arr.length; j++) { + l = arr[l] > arr[j] ? j : l; + } + swap(arr, l, i); + } + + } + /** * 功能描述 : 交换 * @author Leo @@ -220,7 +234,7 @@ public class SelectionSort { for (int i = 0; i < testOfTime; i++) { int[] arr = ArrayUtil.randomArray(maxSize, range); int[] anotherArr = ArrayUtil.copyArray(arr); - selectionSort12(arr); + selectionSort13(arr); Arrays.sort(anotherArr); if (!ArrayUtil.isEqual(arr, anotherArr)) { succeed = false; diff --git a/src/leo/class01_02/EvenTimesOddTimes.java b/src/leo/class01_02/EvenTimesOddTimes.java index d83147f..0ec3279 100644 --- a/src/leo/class01_02/EvenTimesOddTimes.java +++ b/src/leo/class01_02/EvenTimesOddTimes.java @@ -83,6 +83,17 @@ public class EvenTimesOddTimes { System.out.println(eor); } + public static void printOdd8(int[] arr) { + if (arr == null || arr.length == 0) { + return; + } + int eor = 0; + for (int i = 0; i < arr.length; i++) { + eor ^= arr[i]; + } + System.out.println(eor); + + } /** * 功能描述 : 有两种数出现了奇数次,找出他 @@ -225,12 +236,27 @@ public class EvenTimesOddTimes { System.out.println(anotherEor + " " + (eor ^ anotherEor)); } + public static void printOddTwo9(int[] arr) { + int eor = 0; + for (int i = 0; i < arr.length; i++) { + eor ^= arr[i]; + } + int right = eor & (-eor); + int antherEor = 0; + for (int num : arr) { + if ((num & right) != 0) { + antherEor ^= num; + } + } + System.out.println(antherEor + " " + (eor ^ antherEor)); + } + public static void main(String[] args){ int[] arrOne = {1, 1, 5, 5, 8, 1, 8, 5, 5}; - printOdd7(arrOne); + printOdd8(arrOne); int[] arrTwo = {1, 1, 9, 5, 5, 8, 1, 8, 9, 5, 5, 5}; - printOddTwo8(arrTwo); + printOddTwo9(arrTwo); } diff --git a/src/leo/class01_02/KM.java b/src/leo/class01_02/KM.java index 83e47ef..ed898d4 100644 --- a/src/leo/class01_02/KM.java +++ b/src/leo/class01_02/KM.java @@ -225,6 +225,44 @@ public class KM { } + public static int onlyKTime8(int[] arr, int k, int m) { + if (arr == null || arr.length == 0) { + return -1; + } + int[] t = new int[32]; + for (int num : arr) { + for (int i = 0; i < t.length; i++) { + t[i] += (num >> i) & 1; + } + } + int ans = 0; + for (int i = 0; i < t.length; i++) { + if (t[i] % m != 0) { + if (t[i] % m == k) { + ans |= (1 << i); + } else { + return -1; + } + } + } + if (ans == 0) { + int count = 0; + for (int num : arr) { + if (num == 0) { + count++; + } + + } + if (count == k) { + return 0; + }else { + return -1; + } + } + return ans; + + } + public static void main(String[] args) { int maxKinds = 20; int range = 50; @@ -241,7 +279,7 @@ public class KM { } int[] arr = randomArray(maxKinds, range, k, m); - int ans = onlyKTime7(arr, k, m); + int ans = onlyKTime8(arr, k, m); int ans2 = testForOnlyKTimes(arr, k, m); if (ans != ans2) { System.out.println(ans); diff --git a/src/leo/class02_03/DeleteGivenValue.java b/src/leo/class02_03/DeleteGivenValue.java index 33e6f35..ab89707 100644 --- a/src/leo/class02_03/DeleteGivenValue.java +++ b/src/leo/class02_03/DeleteGivenValue.java @@ -147,6 +147,54 @@ public class DeleteGivenValue { } + public static Node removeNodeOfValue5(Node head, int value) { + if (head == null) { + return null; + } + while (head != null) { + if (head.value != value) { + break; + } + head = head.next; + } + Node cur = head; + Node pre = head; + while (cur != null) { + if (cur.value == value) { + pre.next = cur.next; + }else{ + pre = cur; + } + cur = cur.next; + + } + return head; + } + + + public static Node removeNodeOfValue6(Node head, int value) { + if (head == null) { + return null; + } + while (head != null) { + if (head.value != value) { + break; + } + head = head.next; + } + Node pre = head; + Node cur = head; + while (cur != null) { + if (cur.value == value) { + pre.next = cur.next; + }else { + pre = cur; + } + cur = cur.next; + } + return head; + } + /** * 功能描述 : 双链表删除某个给定值 * @author Leo @@ -339,6 +387,35 @@ public class DeleteGivenValue { return head; } + + public static DoubleNode removeDoubleNodeOfValue7(DoubleNode head,int value) { + if (head == null) { + return null; + } + while (head != null) { + if (head.value != value) { + head.pre = null; + break; + } + head = head.next; + } + + DoubleNode pre = head; + DoubleNode cur = head; + while (cur != null) { + if (cur.value == value) { + pre.next = cur.next; + cur.pre = null; + if (cur.next != null) { + pre.next.pre = pre; + } + } else { + pre = cur; + } + cur = cur.next; + } + return head; + } /** * 功能描述 : 验证单链表删除结果 * @author Leo @@ -445,14 +522,14 @@ public class DeleteGivenValue { for (int i = 0; i < testTime; i++) { int value = randomInt(range); Node nodeHead = randomNode(sizeMax, range); - Node node = removeNodeOfValue4(nodeHead, value); + Node node = removeNodeOfValue6(nodeHead, value); if (!verifyRemoveNodeOfValue(node,value)) { System.out.println("node fuck!"); break; } DoubleNode doubleNodeHead = randomDoubleNode(sizeMax, range); - DoubleNode doubleNode = removeDoubleNodeOfValue6(doubleNodeHead, value); + DoubleNode doubleNode = removeDoubleNodeOfValue7(doubleNodeHead, value); if (!verifyRemoveDoubleNodeOfValue(doubleNode, value)) { System.out.println("doubleNode fuck"); break; diff --git a/src/leo/class02_03/GetMax.java b/src/leo/class02_03/GetMax.java index a7053bc..fdee230 100644 --- a/src/leo/class02_03/GetMax.java +++ b/src/leo/class02_03/GetMax.java @@ -42,6 +42,22 @@ public class GetMax { return Math.max(leftMax, rightMax); } + private static int getMax2(int[] arr) { + if (arr.length == 0 || arr == null) { + return 0; + } + return process2(arr, 0, arr.length-1); + } + + private static int process2(int[] arr, int l, int r) { + if (l == r) { + return arr[l]; + } + int m = l + ((r - l) >> 1); + int left = process2(arr, l, m); + int right = process2(arr, m + 1, r); + return Math.max(left, right); + } private static int testGetMax(int[] arr) { Arrays.sort(arr); return arr[arr.length - 1]; @@ -55,7 +71,7 @@ public class GetMax { for (int i = 0; i < testTime; i++) { int[] arr = ArrayUtil.randomAdjacentNotEqualArray(maxSize, range); - int max = getMax1(arr); + int max = getMax2(arr); int testMax = testGetMax(arr); if (max != testMax) { System.out.println("fuck"); diff --git a/src/leo/class02_03/GetMinStack.java b/src/leo/class02_03/GetMinStack.java index c32f4c3..b832156 100644 --- a/src/leo/class02_03/GetMinStack.java +++ b/src/leo/class02_03/GetMinStack.java @@ -1,5 +1,7 @@ package leo.class02_03; +import sun.jvm.hotspot.jdi.IntegerTypeImpl; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -177,6 +179,43 @@ public class GetMinStack { } } + public static class MyStack9 { + Stack data; + Stack min; + + public MyStack9() { + this.data = new Stack<>(); + this.min = new Stack<>(); + } + + public void push(int v) { + if (min.size() == 0) { + min.push(v); + } else if (getMin() >= v) { + min.push(v); + } + this.data.push(v); + } + + public int pop() { + Integer v = this.data.pop(); + if (v == getMin()) { + this.min.pop(); + } + return v; + } + public int getMin() { + if (this.min.isEmpty()) { + throw new RuntimeException("Stack is Empty"); + } + return this.min.peek(); + } + + public boolean isEmpty() { + return data.size() == 0; + } + } + /** * 只有最小值入栈,最小值重复入栈 */ @@ -342,6 +381,47 @@ public class GetMinStack { } } + public static class MyStack10 { + Stack data; + Stack min; + + public MyStack10() { + this.data = new Stack<>(); + this.min = new Stack<>(); + } + + public boolean isEmpty() { + return data.size() == 0; + } + + public void push(int v) { + if (min.isEmpty()) { + min.push(v); + } else if (getMin() > v) { + this.min.push(v); + }else { + min.push(this.min.peek()); + } + this.data.push(v); + } + + public int pop() { + if (data.isEmpty()) { + throw new RuntimeException("Stack is Empty"); + } + Integer v = data.pop(); + this.min.pop(); + return v; + } + + public int getMin() { + if (this.min.isEmpty()) { + throw new RuntimeException("Stack is Empty"); + } + return this.min.peek(); + } + } + /** * 用list实现 只存最小值的索引 */ @@ -432,7 +512,7 @@ public class GetMinStack { System.out.println("Start!"); for (int i = 0; i < testTime; i++) { - MyStack8 myStack = new MyStack8(); + MyStack10 myStack = new MyStack10(); TestMyStack testMyStack = new TestMyStack(); for (int j = 0; j < forTime; j++) { if (Math.random() < 0.5) { diff --git a/src/leo/class02_03/LinkedList.java b/src/leo/class02_03/LinkedList.java index 40cd5fc..f54303f 100644 --- a/src/leo/class02_03/LinkedList.java +++ b/src/leo/class02_03/LinkedList.java @@ -195,6 +195,21 @@ public class LinkedList { return pre; } + public static Node reverseNode12(Node head) { + if (head == null) { + return null; + } + Node pre = null; + Node next = null; + while (head != null) { + next = head.next; + head.next = pre; + pre = head; + head = next; + } + return pre; + } + public static DoubleNode reverseDoubleNode(DoubleNode head) { DoubleNode pre = null; DoubleNode next; @@ -438,7 +453,7 @@ public class LinkedList { for (int i = 0; i < testTime; i++) { Node head = randomNode(maxSize, range); List nodeList = nodeToList(head); - Node node = reverseNode11(head); + Node node = reverseNode12(head); if (!verifyReverseListAndNode(nodeList, node)) { System.out.println("nodeFuck!!"); break; diff --git a/src/leo/class02_03/RingArray.java b/src/leo/class02_03/RingArray.java index e2a0029..d8e6ebb 100644 --- a/src/leo/class02_03/RingArray.java +++ b/src/leo/class02_03/RingArray.java @@ -226,13 +226,52 @@ public class RingArray { } + public static class MyQueue5 { + int[] arr ; + int size; + int offer; + int poll; + final int limit; + + public MyQueue5(int limit) { + this.arr = new int[limit]; + this.size = 0; + this.offer = 0; + this.poll = 0; + this.limit = limit; + } + + public boolean isEmpty() { + return this.size == 0; + } + public void push(int v){ + if (size == limit) { + throw new RuntimeException("queue is full"); + } + arr[offer] = v; + size++; + offer = offer < limit - 1 ? offer + 1 : 0; + } + + public int poll() { + if (size == 0) { + throw new RuntimeException("queue is empty"); + } + int v = arr[poll]; + size--; + poll = poll < limit - 1 ? poll + 1 : 0; + return v; + } + + } + public static void main(String[] args) { int testTime = 10000; int range = 100; int sizeMax = 80; for (int i = 0; i < testTime; i++) { int length = randomInt(sizeMax); - MyQueue4 myQueue = new MyQueue4(length); + MyQueue5 myQueue = new MyQueue5(length); Queue queue = new LinkedList<>(); for (int j = 0; j < length; j++) { int value = randomInt(range); diff --git a/src/leo/class02_03/StackAndQueue.java b/src/leo/class02_03/StackAndQueue.java index d03ce7b..ede8b69 100644 --- a/src/leo/class02_03/StackAndQueue.java +++ b/src/leo/class02_03/StackAndQueue.java @@ -370,7 +370,81 @@ public class StackAndQueue { } + public static class DoubleNodeStackAndQueue1 { + class DoubleNode{ + T value; + DoubleNode pre; + DoubleNode next; + public DoubleNode(T v){ + this.value = v; + } + } + private DoubleNode tail; + private DoubleNode head; + + public void pushHead(T v) { + DoubleNode node = new DoubleNode(v); + if (head == null) { + tail = node; + head = node; + }else { + node.next = head; + head.pre = node; + head = node; + } + } + public void pushTail(T v) { + DoubleNode node = new DoubleNode(v); + if (tail == null) { + tail = node; + head = node; + }else { + tail.next = node; + node.pre = tail; + tail = node; + } + } + + public T popHead() { + if (head == null) { + return null; + } + T v = head.value; + if (head.next != null) { + head = head.next; + head.pre.next = null; + head.pre = null; + } else { + head = null; + tail = null; + } + return v; + } + + public T popTail() { + if (tail == null) { + return null; + } + T value = tail.value; + if (tail.pre == null) { + tail = null; + head = null; + } else { + tail = tail.pre; + tail.next.pre = null; + tail.next = null; + } + return value; + } + + public boolean isEmpty() { + return head == null; + } + + + + } /** * @author Leo @@ -481,6 +555,27 @@ public class StackAndQueue { } + public static class MyStack4{ + + private DoubleNodeStackAndQueue1 myStack; + + public MyStack4() { + myStack = new DoubleNodeStackAndQueue1(); + } + + public void push(T value) { + myStack.pushHead(value); + } + + public T pop() { + return myStack.popHead(); + } + + public boolean isEmpty() { + return myStack.isEmpty(); + } + } + @@ -587,6 +682,25 @@ public class StackAndQueue { } } + public static class MyQueue4 { + DoubleNodeStackAndQueue1 myQueue; + + public MyQueue4() { + myQueue = new DoubleNodeStackAndQueue1<>(); + } + + public void push(T v) { + myQueue.pushHead(v); + } + + public T poll() { + return myQueue.popTail(); + } + + public boolean isEmpty() { + return myQueue.isEmpty(); + } + } public static boolean isEqual(Integer o1, Integer o2) { @@ -607,8 +721,8 @@ public class StackAndQueue { int forTime = 1000; int range = 8000; for (int i = 0; i < forTime; i++) { - MyStack3 myStack = new MyStack3<>(); - MyQueue3 myQueue = new MyQueue3<>(); + MyStack4 myStack = new MyStack4<>(); + MyQueue4 myQueue = new MyQueue4<>(); Stack stack = new Stack<>(); Queue queue = new LinkedList<>(); for (int j = 0; j < testTime; j++) { diff --git a/src/leo/class09_14/BestArrange.java b/src/leo/class09_14/BestArrange.java new file mode 100644 index 0000000..6887383 --- /dev/null +++ b/src/leo/class09_14/BestArrange.java @@ -0,0 +1,170 @@ +package leo.class09_14; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * @author Leo + * @ClassName BestArrange + * @DATE 2020/12/22 4:22 下午 + * @Description 贪心策略 + * 1353. 最多可以参加的会议数目 + * 一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。 + * 给你每一个项目开始的时间和结束的时间 + * 你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。 + * 返回最多的宣讲场次。 + */ +public class BestArrange { + public static class Program { + public int start; + public int end; + + public Program(int start, int end) { + this.start = start; + this.end = end; + } + } + + static class Code { + static class ProgramComparator implements Comparator { + + @Override + public int compare(Program o1, Program o2) { + return o1.end - o2.end; + } + } + public static int bestArrange(Program[] program) { + Arrays.sort(program, new ProgramComparator()); + int end = 0; + int result = 0; + for (int i = 0; i < program.length; i++) { + if (end <= program[i].start) { + result++; + end = program[i].end; + } + } + return result; + } + + } + + static class Code1 { + + public static int bestArrange(Program[] program) { + Arrays.sort(program, new ProgramComparator()); + int res = 0; + int end = 0; + for (int i = 0; i < program.length; i++) { + if (end <= program[i].start) { + res++; + end = program[i].end; + } + } + return res; + } + + static class ProgramComparator implements Comparator { + public int compare(Program p1, Program p2) { + return p1.end - p2.end; + } + } + } + + static class Code2 { + static int bestArrange(Program[] program) { + Arrays.sort(program, new ProgramComparator()); + int end = 0; + int count = 0; + for (int i = 0; i < program.length; i++) { + if (end <= program[i].start) { + count++; + end = program[i].end; + } + } + return count; + } + + static class ProgramComparator implements Comparator { + @Override + public int compare(Program o1, Program o2) { + return o1.end - o2.end; + } + + } + } + + static class Violence { + // 暴力!所有情况都尝试! + public static int bestArrange1(Program[] programs) { + if (programs == null || programs.length == 0) { + return 0; + } + return process(programs, 0, 0); + } + + // 还剩下的会议都放在programs里 + // done之前已经安排了多少会议的数量 + // timeLine目前来到的时间点是什么 + + // 目前来到timeLine的时间点,已经安排了done多的会议,剩下的会议programs可以自由安排 + // 返回能安排的最多会议数量 + public static int process(Program[] programs, int done, int timeLine) { + if (programs.length == 0) { + return done; + } + // 还剩下会议 + int max = done; + // 当前安排的会议是什么会,每一个都枚举 + for (int i = 0; i < programs.length; i++) { + if (programs[i].start >= timeLine) { + Program[] next = copyButExcept(programs, i); + max = Math.max(max, process(next, done + 1, programs[i].end)); + } + } + return max; + } + + public static Program[] copyButExcept(Program[] programs, int i) { + Program[] ans = new Program[programs.length - 1]; + int index = 0; + for (int k = 0; k < programs.length; k++) { + if (k != i) { + ans[index++] = programs[k]; + } + } + return ans; + } + + } + + + // for test + public static Program[] generatePrograms(int programSize, int timeMax) { + Program[] ans = new Program[(int) (Math.random() * (programSize + 1))]; + for (int i = 0; i < ans.length; i++) { + int r1 = (int) (Math.random() * (timeMax + 1)); + int r2 = (int) (Math.random() * (timeMax + 1)); + if (r1 == r2) { + ans[i] = new Program(r1, r1 + 1); + } else { + ans[i] = new Program(Math.min(r1, r2), Math.max(r1, r2)); + } + } + return ans; + } + + public static void main(String[] args) { + int programSize = 12; + int timeMax = 20; + int timeTimes = 1000000; + for (int i = 0; i < timeTimes; i++) { + Program[] programs = generatePrograms(programSize, timeMax); + if (Code2.bestArrange(programs) != Violence.bestArrange1(programs)) { + System.out.println("Oops!"); + } + } + System.out.println("finish!"); + } +} + diff --git a/src/leo/class09_14/IPO.java b/src/leo/class09_14/IPO.java new file mode 100644 index 0000000..597bd64 --- /dev/null +++ b/src/leo/class09_14/IPO.java @@ -0,0 +1,75 @@ +package leo.class09_14; + +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * @author Leo + * @ClassName IPO + * @DATE 2020/12/22 5:17 下午 + * @Description + * 输入: 正数数组costs、正数数组profits、正数K、正数M + * costs[i]表示i号项目的花费 + * profits[i]表示i号项目在扣除花费之后还能挣到的钱(利润) + * K表示你只能串行的最多做k个项目 + * M表示你初始的资金 + * 说明: 每做完一个项目,马上获得的收益,可以支持你去做下一个项目。不能并行的做项目。 + * 输出:你最后获得的最大钱数。 + */ +public class IPO { + + + /** + * 功能描述 : + * @author Leo + * @date 2020/12/22 5:56 下午 + * @param K 能做几次项目 + * @param W 初始资金 + * @param Profits 收益 + * @param Capital 成本 + * @throw + * @return int + */ + public static int findMaximizedCapital(int K, int W, int[] Profits, int[] Capital) { + + PriorityQueue minC = new PriorityQueue<>(new MinCComparator()); + PriorityQueue maxP = new PriorityQueue<>(new MaxPComparator()); + for (int i = 0; i < Profits.length; i++) { + minC.add(new Program(Profits[i], Capital[i])); + } + for (int i = 0; i < K; i++) { + while (!minC.isEmpty() && minC.peek().c <= W) { + maxP.add(minC.poll()); + } + if (maxP.isEmpty()) { + return W; + } + W += maxP.poll().p; + } + return W; + } + static class MinCComparator implements Comparator { + public int compare(Program p1, Program p2) { + return p1.c - p2.c; + } + } + + static class MaxPComparator implements Comparator { + public int compare(Program p1,Program p2) { + return p2.p - p1.p; + } + + } + + static class Program { + //收益 + int p; + //成本 + int c; + + public Program(int p, int c) { + this.p = p; + this.c = c; + } + } +} diff --git a/src/leo/class09_14/LessMoneySplitGold.java b/src/leo/class09_14/LessMoneySplitGold.java new file mode 100644 index 0000000..c0d08a5 --- /dev/null +++ b/src/leo/class09_14/LessMoneySplitGold.java @@ -0,0 +1,119 @@ +package leo.class09_14; + +import java.util.PriorityQueue; + +/** + * @author Leo + * @ClassName LessMoneySplitGold + * @DATE 2020/12/22 4:54 下午 + * @Description + * 贪心策略 + * 一块金条切成两半,是需要花费和长度数值一样的铜板的。 + * 比如长度为20的金条,不管怎么切,都要花费20个铜板。 一群人想整分整块金条,怎么分最省铜板? + * + * 例如,给定数组{10,20,30},代表一共三个人,整块金条长度为60,金条要分成10,20,30三个部分。 + * + * 如果先把长度60的金条分成10和50,花费60; 再把长度50的金条分成20和30,花费50;一共花费110铜板。 + * 但如果先把长度60的金条分成30和30,花费60;再把长度30金条分成10和20, 花费30;一共花费90铜板。 + * 输入一个数组,返回分割的最小代价。 + */ +public class LessMoneySplitGold { + + static class Code { + static int lessMoney(int[] arr) { + PriorityQueue queue = new PriorityQueue<>(); + for (int i = 0; i < arr.length; i++) { + queue.offer(arr[i]); + } + int sum = 0; + int cur = 0; + while (queue.size() > 1) { + cur = queue.poll() + queue.poll(); + sum += cur; + queue.offer(cur); + } + return sum; + } + + } + + static class Code1 { + static int lessMoney(int[] arr) { + PriorityQueue queue = new PriorityQueue<>(); + for (int i = 0; i < arr.length; i++) { + queue.offer(arr[i]); + } + int sum = 0; + int cur = 0; + while (queue.size() > 1) { + cur = queue.poll() + queue.poll(); + sum += cur; + queue.offer(cur); + } + return sum; + } + + } + + static class Violence { + // 纯暴力! + public static int lessMoney(int[] arr) { + if (arr == null || arr.length == 0) { + return 0; + } + return process(arr, 0); + } + + // 等待合并的数都在arr里,pre之前的合并行为产生了多少总代价 + // arr中只剩一个数字的时候,停止合并,返回最小的总代价 + public static int process(int[] arr, int pre) { + if (arr.length == 1) { + return pre; + } + int ans = Integer.MAX_VALUE; + for (int i = 0; i < arr.length; i++) { + for (int j = i + 1; j < arr.length; j++) { + ans = Math.min(ans, process(copyAndMergeTwo(arr, i, j), pre + arr[i] + arr[j])); + } + } + return ans; + } + + public static int[] copyAndMergeTwo(int[] arr, int i, int j) { + int[] ans = new int[arr.length - 1]; + int ansi = 0; + for (int arri = 0; arri < arr.length; arri++) { + if (arri != i && arri != j) { + ans[ansi++] = arr[arri]; + } + } + ans[ansi] = arr[i] + arr[j]; + return ans; + } + + } + + + // for test + public static int[] generateRandomArray(int maxSize, int maxValue) { + int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; + for (int i = 0; i < arr.length; i++) { + arr[i] = (int) (Math.random() * (maxValue + 1)); + } + return arr; + } + + public static void main(String[] args) { + int testTime = 100000; + int maxSize = 6; + int maxValue = 1000; + System.out.println("start"); + for (int i = 0; i < testTime; i++) { + int[] arr = generateRandomArray(maxSize, maxValue); + if (Violence.lessMoney(arr) != Code1.lessMoney(arr)) { + System.out.println("Oops!"); + } + } + System.out.println("end!"); + } +} diff --git a/src/leo/class09_14/Light.java b/src/leo/class09_14/Light.java new file mode 100644 index 0000000..5d22a6e --- /dev/null +++ b/src/leo/class09_14/Light.java @@ -0,0 +1,103 @@ +package leo.class09_14; + +import java.util.HashSet; + +/** + * @author Leo + * @ClassName Light + * @DATE 2020/12/22 4:19 下午 + * @Description + * 给定一个字符串str,只由‘X’和‘.’两种字符构成。 + * ‘X’表示墙,不能放灯,也不需要点亮 + * ‘.’表示居民点,可以放灯,需要点亮 + * 如果灯放在i位置,可以让i-1,i和i+1三个位置被点亮 + * 返回如果点亮str中所有需要点亮的位置,至少需要几盏灯 + */ +public class Light { + + static class Code { + static int minLight(String s) { + if (s == null || s.length() == 0) { + return 0; + } + char[] chars = s.toCharArray(); + int i = 0; + int l = 0; + while (i < chars.length) { + if (chars[i] == 'X') { + i++; + }else{ + l++; + if (i + 1 == chars.length) { + break; + } else if (chars[i + 1] == 'X') { + i += 2; + }else { + i += 3; + } + } + } + return l; + } + } + + static class Violence { + public static int minLight(String road) { + if (road == null || road.length() == 0) { + return 0; + } + return process(road.toCharArray(), 0, new HashSet<>()); + } + + // str[index....]位置,自由选择放灯还是不放灯 + // str[0..index-1]位置呢?已经做完决定了,那些放了灯的位置,存在lights里 + // 要求选出能照亮所有.的方案,并且在这些有效的方案中,返回最少需要几个灯 + public static int process(char[] str, int index, HashSet lights) { + if (index == str.length) { // 结束的时候 + for (int i = 0; i < str.length; i++) { + if (str[i] != 'X') { // 当前位置是点的话 + if (!lights.contains(i - 1) && !lights.contains(i) && !lights.contains(i + 1)) { + return Integer.MAX_VALUE; + } + } + } + return lights.size(); + } else { // str还没结束 + // i X . + int no = process(str, index + 1, lights); + int yes = Integer.MAX_VALUE; + if (str[index] == '.') { + lights.add(index); + yes = process(str, index + 1, lights); + lights.remove(index); + } + return Math.min(no, yes); + } + } + } + + // for test + public static String randomString(int len) { + char[] res = new char[(int) (Math.random() * len) + 1]; + for (int i = 0; i < res.length; i++) { + res[i] = Math.random() < 0.5 ? 'X' : '.'; + } + return String.valueOf(res); + } + + public static void main(String[] args) { + int len = 20; + int testTime = 100000; + System.out.println("start"); + for (int i = 0; i < testTime; i++) { + String test = randomString(len); + int ans1 = Violence.minLight(test); + int ans2 = Code.minLight(test); + if (ans1 != ans2) { + System.out.println("oops!"); + } + } + System.out.println("finish!"); + } + +} diff --git a/src/leo/class09_14/UnionFindClass.java b/src/leo/class09_14/UnionFindClass.java new file mode 100644 index 0000000..32f8e9d --- /dev/null +++ b/src/leo/class09_14/UnionFindClass.java @@ -0,0 +1,83 @@ +package leo.class09_14; + +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +/** + * @author Leo + * @ClassName UnionFind + * @DATE 2020/12/23 11:31 上午 + * @Description 并查集 + */ +public class UnionFindClass { + + static class Node{ + V value; + public Node(V v){ + this.value = v; + } + } + + public class UnionFind { + HashMap> nodes; + HashMap,Node> parents; + HashMap, Integer> sizeMap; + + + public UnionFind(List list) { + nodes = new HashMap<>(); + parents = new HashMap<>(); + sizeMap = new HashMap<>(); + for (V v : list) { + Node node = new Node(v); + nodes.put(v, node); + parents.put(node, node); + sizeMap.put(node, 1); + } + + } + + + public void union(V a,V b) { + Node aF = findFather(a); + Node bF = findFather(b); + if (aF != bF) { + Integer aSize = sizeMap.get(a); + Integer bSize = sizeMap.get(b); + Node big = aSize >= bSize ? aF : bF; + Node small = big == aF ? bF : aF; + parents.put(small, big); + sizeMap.put(big, bSize + aSize); + sizeMap.remove(small); + } + } + //判断两个变量是否处于同一个集合. + public boolean isSameSet(V a,V b){ + Node aF = findFather(a); + Node bF = findFather(b); + return aF == bF; + } + //找顶级父节点. + public Node findFather(V v){ + Stack> stack = new Stack<>(); + Node cur = nodes.get(v); + //如果顶级父节点不是自己,就代表还有父节点. + while (cur != parents.get(cur)) { + //记录找过的父节点 + stack.push(cur); + cur = parents.get(cur); + } + //将找过的父节点的父节点设置为顶级父节点 + while (!stack.isEmpty()) { + parents.put(stack.pop(), cur); + } + return cur; + } + + public int sets() { + return sizeMap.size(); + } + } + +} diff --git a/src/leo/class09_15/FriendCircles.java b/src/leo/class09_15/FriendCircles.java new file mode 100644 index 0000000..b5862c6 --- /dev/null +++ b/src/leo/class09_15/FriendCircles.java @@ -0,0 +1,79 @@ +package leo.class09_15; + +/** + * @author Leo + * @ClassName FriendCircles + * @DATE 2020/12/23 2:49 下午 + * @Description + * 547 测试链接:https://leetcode.com/problems/friend-circles/ + */ +public class FriendCircles { + + public int findCircleNum(int[][] M) { + int n = M.length; + UnionFind unionFind = new UnionFind(n); + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + if (M[i][j] == 1) { + unionFind.union(i, j); + } + } + + } + return unionFind.sets; + } + + + public class UnionFind { + // i的父级节点是parent[i] + int[] parent; + // i的集合大小为size[i] + int[] size; + //辅助结构 + int[] help; + //一共多少个集合 + int sets; + public UnionFind(int n) { + + parent = new int[n]; + size = new int[n]; + help = new int[n]; + sets = n; + for (int i = 0; i < n; i++) { + parent[i] = i; + size[i] = 1; + } + } + + public int find(int i) { + int h = 0; + while (i != parent[i]) { + help[h++] = i; + i = parent[i]; + } + for (h--; h >= 0; h--) { + parent[help[h]] = i; + } + return i; + } + + + public void union(int i, int j) { + int iF = find(i); + int jF = find(j); + if (jF != iF) { + int iSize = size[iF]; + int jSize = size[jF]; + int big = iSize >= jSize ? iF : jF; + int small = big == iF ? jF : iF; + parent[small] = big; + size[big] = jSize + iSize; + sets--; + } + } + + public int sets() { + return sets; + } + } +} diff --git a/src/leo/class09_15/NumberOfIslands.java b/src/leo/class09_15/NumberOfIslands.java new file mode 100644 index 0000000..594e97e --- /dev/null +++ b/src/leo/class09_15/NumberOfIslands.java @@ -0,0 +1,257 @@ +package leo.class09_15; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +/** + * @author Leo + * @ClassName NumberOfIslands + * @DATE 2020/12/23 3:26 下午 + * @Description 岛问题1 + * 200 + * 测试链接:https://leetcode.com/problems/number-of-islands/ + */ +public class NumberOfIslands { + + static class Code1 { + static class C{ + public static int numIslands(char[][] grid) { + int count = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == '1') { + count++; + infect(grid, i, j); + } + } + } + return count; + } + + private static void infect(char[][] grid, int r, int c) { + if (r < 0 || r == grid.length || c < 0 || c == grid[0].length || grid[r][c] != '1') { + return; + } + grid[r][c] = '2'; + infect(grid, r-1, c); + infect(grid, r+1, c); + infect(grid, r, c-1); + infect(grid, r, c+1); + } + } + + } + + static class Code2 { + + static class C { + public static int numIslands(char[][] grid) { + List list = new ArrayList<>(); + int r = grid.length; + int c = grid[0].length; + Dot[][] dot = new Dot[r][c]; + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { + if (grid[i][j] == '1') { + dot[i][j] = new Dot(); + list.add(dot[i][j]); + } + } + } + UnionFind unionFind = new UnionFind<>(list); + //第一列每一行与上面合并, + for (int i = 1; i < r; i++) { + if (grid[i - 1][0] == '1' && grid[i][0] == '1') { + unionFind.union(dot[i - 1][0], dot[i][0]); + } + } + //第一行每一列与左面合并. + for (int i = 1; i < c; i++) { + if (grid[0][i - 1] == '1' && grid[0][i] == '1') { + unionFind.union(dot[0][i - 1], dot[0][i]); + } + } + //除了第一行和第一列 每个位置与自己的左侧和上方合并. + for (int i = 1; i < r; i++) { + for (int j = 1; j < c; j++) { + if (grid[i][j] == '1') { + if (grid[i - 1][j] == '1') { + unionFind.union(dot[i][j], dot[i - 1][j]); + } + if (grid[i][j - 1] == '1') { + unionFind.union(dot[i][j], dot[i][j - 1]); + + } + + } + } + } + return unionFind.sets(); + } + static class UnionFind { + HashMap> nodes ; + HashMap,Node> parents; + HashMap,Integer> sizeMap; + public UnionFind(List list){ + nodes = new HashMap<>(); + parents = new HashMap<>(); + sizeMap = new HashMap<>(); + for (V dot : list) { + Node node = new Node(dot); + nodes.put(dot, node); + parents.put(node, node); + sizeMap.put(node, 1); + } + } + + public Node find(Node node) { + Stack stack = new Stack<>(); + while (node != parents.get(node)) { + stack.push(node); + node = parents.get(node); + } + while (!stack.isEmpty()) { + parents.put(stack.pop(), node); + } + return node; + } + + public void union(V a, V b) { + Node aF = find(nodes.get(a)); + Node bF = find(nodes.get(b)); + if (aF != bF) { + int aSize = sizeMap.get(aF); + int bSize = sizeMap.get(bF); + Node big = aSize >= bSize ? aF : bF; + Node small = big == aF ? bF : aF; + parents.put(small, big); + sizeMap.put(big, aSize + bSize); + sizeMap.remove(small); + } + } + + public int sets() { + return sizeMap.size(); + } + } + static class Dot { + + } + static class Node { + V value; + public Node(V v) { + this.value = v; + } + } + } + + + } + + static class Code3 { + //row col 对应下标 row * colTotal + col + static class C { + public static int numIslands(char[][] grid) { + int row = grid.length; + int col = grid[0].length; + UnionFind u = new UnionFind(grid); + //第一列中的元素与上合并 + for (int i = 1; i < row; i++) { + if (grid[i - 1][0] == '1' && grid[i][0] == '1') { + u.union(i - 1, 0, i, 0); + } + } + //第一行中的元素与左和合并 + for (int i = 1; i < col; i++) { + if (grid[0][i - 1] == '1' && grid[0][i] == '1') { + u.union(0, i - 1, 0, i); + } + } + //除了第一行和第一列每个元素与上 左 合并 + for (int i = 1; i < row; i++) { + for (int j = 1; j < col; j++) { + if (grid[i][j] == '1') { + if (grid[i - 1][j] == '1') { + u.union(i, j, i - 1, j); + } + if (grid[i][j - 1] == '1') { + u.union(i, j, i, j - 1); + } + } + + } + } + return u.sets(); + } + + static class UnionFind { + int[] parent; + int[] size; + int[] help; + int sets; + int col; + + public UnionFind(char[][] grid) { + int row = grid.length; + col = grid[0].length; + int n = row * col; + parent = new int[n]; + size = new int[n]; + help = new int[n]; + sets = 0; + for (int i = 0; i < row; i++) { + for (int j = 0; j < col; j++) { + if (grid[i][j] == '1') { + int index = getIndex(i, j); + parent[index] = index; + size[index] = 1; + sets++; + } + } + } + } + + public int find(int i) { + int h = 0; + while (i != parent[i]) { + help[h++] = i; + i = parent[i]; + } + for (h--; h >= 0; h--) { + parent[help[h]] = i; + } + return i; + } + + public void union(int r1, int c1, int r2, int c2) { + int i1 = getIndex(r1, c1); + int i2 = getIndex(r2, c2); + int aF = find(i1); + int bF = find(i2); + if (aF != bF) { + int aSize = size[aF]; + int bSize = size[bF]; + int big = aSize >= bSize ? aF : bF; + int small = big == aF ? bF : aF; + parent[small] = big; + size[big] = bSize + aSize; + sets--; + } + } + + public int sets() { + return sets; + } + int getIndex(int r, int c) { + return r * col + c; + } + } + + + + } + } + +}