├── basic_class_nowcoder └── src │ ├── class_08 │ ├── Test.java │ ├── Code_01_Factorial.java │ ├── FaceBook.java │ ├── Code_06_ReverseStackUsingRecursive.java │ ├── Code_05_Cow.java │ ├── Code_08_Money_Problem.java │ ├── Code_03_Print_All_Subsquences.java │ ├── Code_09_Knapsack.java │ ├── Code_02_Hanoi.java │ ├── Code_04_Print_All_Permutations.java │ └── Code_07_MinPath.java │ ├── class_06 │ ├── Edge.java │ ├── Graph.java │ ├── Node.java │ ├── Code_01_BFS.java │ ├── Code_02_DFS.java │ ├── GraphGenerator.java │ ├── Code_03_TopologySort.java │ ├── Code_05_Prim.java │ ├── Code_04_Kruskal.java │ └── Code_06_Dijkstra.java │ ├── class_05 │ ├── class_05_bulongguolvqi.java │ ├── Code_04_UnionFind.java │ ├── Code_03_Islands.java │ ├── Code_02_RandomPool.java │ └── Code_01_HashMap.java │ ├── class_04 │ ├── Code_05_PaperFolding.java │ ├── Code_08_CompleteTreeNodeNumber.java │ ├── Code_06_IsBalancedTree.java │ ├── Code_02_PrintBinaryTree.java │ ├── Code_03_SuccessorNode.java │ ├── Code_07_IsBSTAndCBT.java │ ├── Code_01_PreInPosTraversal.java │ └── Code_04_SerializeAndReconstructTree.java │ ├── class_07 │ ├── Code_05_LowestLexicography.java │ ├── Code_06_BestArrange.java │ ├── Code_03_IPO.java │ ├── Code_02_Less_Money.java │ ├── Code_01_TrieTree.java │ └── Code_04_MadianQuick.java │ ├── class_03 │ ├── Code_09_FindNumInSortedMatrix.java │ ├── Code_15_FindOneLessValueIndex.java │ ├── Code_08_ZigZagPrintMatrix.java │ ├── Code_06_PrintMatrixSpiralOrder.java │ ├── Code_05_RotateMatrix.java │ ├── Code_10_PrintCommonPart.java │ ├── Code_01_Array_To_Stack_Queue.java │ ├── Code_03_StackAndQueueConvert.java │ ├── Code_07_ReverseList.java │ ├── Code_02_GetMinStack.java │ ├── Code_13_CopyListWithRandom.java │ ├── Code_12_SmallerEqualBigger.java │ ├── Code_04_DogCatQueue.java │ ├── Code_14_FindFirstIntersectNode.java │ └── Code_11_IsPalindromeList.java │ ├── basic_class_02 │ ├── Code_04_Manacher.java │ ├── Code_01_KMP.java │ ├── Code_02_KMP_ShortestHaveTwice.java │ ├── Code_05_Manacher_ShortestEnd.java │ ├── Code_03_KMP_T1SubtreeEqualsT2.java │ └── Code_06_BFPRT.java │ └── basic_class_01 │ ├── Code_08_NetherlandsFlag.java │ ├── Code_09_Comparator.java │ ├── Code_01_InsertionSort.java │ ├── Code_11_MaxGap.java │ ├── Code_02_SelectionSort.java │ ├── Code_06_BucketSort.java │ ├── Code_10_GetAllNotIncluded.java │ ├── Code_00_BubbleSort.java │ ├── Code_04_QuickSort.java │ ├── Code_12_SmallSum.java │ ├── Code_03_HeapSort.java │ ├── Code_07_RadixSort.java │ └── Code_05_MergeSort.java └── README.md /basic_class_nowcoder/src/class_08/Test.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | 3 | public class Test { 4 | 5 | public static int f(int N) { 6 | if(N == 1 || N ==2) { 7 | return 1; 8 | } 9 | return f(N-1) + f(N-2); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Edge.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | /** 3 | * 4 | * 图的边 5 | * 6 | */ 7 | public class Edge { 8 | public int weight;//权重 9 | public Node from; 10 | public Node to; 11 | 12 | public Edge(int weight, Node from, Node to) { 13 | this.weight = weight; 14 | this.from = from; 15 | this.to = to; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Graph.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | /** 6 | * 7 | * 图 8 | * 9 | */ 10 | public class Graph { 11 | public HashMap nodes; 12 | public HashSet edges; 13 | 14 | public Graph() { 15 | nodes = new HashMap<>(); 16 | edges = new HashSet<>(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Node.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.ArrayList; 4 | /** 5 | * 6 | * 图的节点 7 | * 8 | */ 9 | public class Node { 10 | public int value; 11 | public int in;//入度 12 | public int out;//出度 13 | public ArrayList nexts;//下一级节点 14 | public ArrayList edges;//边 15 | 16 | public Node(int value) { 17 | this.value = value; 18 | in = 0; 19 | out = 0; 20 | nexts = new ArrayList<>(); 21 | edges = new ArrayList<>(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_01_Factorial.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * 求n!的结果 5 | * 6 | */ 7 | public class Code_01_Factorial { 8 | //递归版本 9 | public static long getFactorial1(int n) { 10 | if (n == 1) { 11 | return 1L; 12 | } 13 | return (long) n * getFactorial1(n - 1); 14 | } 15 | //非递归版本 16 | public static long getFactorial2(int n) { 17 | long result = 1L; 18 | for (int i = 1; i <= n; i++) { 19 | result *= i; 20 | } 21 | return result; 22 | } 23 | 24 | public static void main(String[] args) { 25 | int n = 5; 26 | System.out.println(getFactorial1(n)); 27 | System.out.println(getFactorial2(n)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Code_01_BFS.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.HashSet; 4 | import java.util.LinkedList; 5 | import java.util.Queue; 6 | /** 7 | * 8 | * BFS图的宽度优先遍历 9 | * 10 | */ 11 | public class Code_01_BFS { 12 | 13 | public static void bfs(Node node) { 14 | if (node == null) { 15 | return; 16 | } 17 | Queue queue = new LinkedList<>(); 18 | HashSet map = new HashSet<>(); 19 | queue.add(node); 20 | map.add(node); 21 | while (!queue.isEmpty()) { 22 | Node cur = queue.poll(); 23 | System.out.println(cur.value); 24 | for (Node next : cur.nexts) { 25 | if (!map.contains(next)) { 26 | map.add(next); 27 | queue.add(next); 28 | } 29 | } 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Code_02_DFS.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.HashSet; 4 | import java.util.Stack; 5 | /** 6 | * 7 | * DFS图的深度优先遍历 8 | * 9 | */ 10 | public class Code_02_DFS { 11 | 12 | public static void dfs(Node node) { 13 | if (node == null) { 14 | return; 15 | } 16 | Stack stack = new Stack<>(); 17 | HashSet set = new HashSet<>(); 18 | stack.add(node); 19 | set.add(node); 20 | System.out.println(node.value); 21 | while (!stack.isEmpty()) { 22 | Node cur = stack.pop(); 23 | for (Node next : cur.nexts) { 24 | if (!set.contains(next)) { 25 | stack.push(cur); 26 | stack.push(next); 27 | set.add(next); 28 | System.out.println(next.value); 29 | break; 30 | } 31 | } 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_05/class_05_bulongguolvqi.java: -------------------------------------------------------------------------------- 1 | package class_05; 2 | ///** 3 | /** 4 | * 布隆过滤器 5 | * 一个int32个bit 6 | * bit类型的数组 7 | * 一个url经过多个hash函数得到hashcode % m 在bit数组中相应位置画黑(数组要足够大,空间越大失误率越小) 8 | * m为bit数组大小 9 | * m = - (n*lnp)/ ( (ln2)^2 ) n为样本量,p为失误率的要求 10 | * k = ln2*m/n k为所需hash函数个数(向上取整) 11 | * 12 | * 实际失误率 (1-e^z)^k z=-n*k/m 13 | */ 14 | public class class_05_bulongguolvqi { 15 | 16 | public static void main(String[] args) { 17 | int []arr = new int [1000];//32000 18 | 19 | int index = 30000; 20 | int intIndex = index / 32; 21 | 22 | int bitIndex = index % 32; 23 | 24 | System.out.println(intIndex); 25 | System.out.println(bitIndex);//放在那个桶 26 | 27 | arr[intIndex] = (arr[intIndex] | (1 << bitIndex)); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/FaceBook.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * 一个数字串,能转变成多少种字母串,有多少种转换方式,数字串对应1-a,2-b等 5 | * 例如1111可以转变成aaaa,aka,kaa,kk,共四种解法 6 | */ 7 | public class FaceBook { 8 | 9 | public static int number(char[] chs, int i) { 10 | if (i == chs.length) { 11 | return 1; 12 | } 13 | if (chs[i] == '0') { 14 | return 0; 15 | } 16 | if (chs[i] == '1') { 17 | int res = number(chs, i + 1); 18 | if(i + 1 < chs.length) { 19 | res += number(chs, i + 2); 20 | } 21 | return res; 22 | } 23 | if (chs[i] == '2') { 24 | int res = number(chs, i + 1); 25 | if (i + 1 < chs.length 26 | && (chs[i + 1] >= '0' && chs[i + 1] <= '6')) { 27 | res += number(chs, i + 2); 28 | } 29 | return res; 30 | } 31 | return number(chs, i+1); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_05_PaperFolding.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | /** 3 | * 4 | * 折纸问题 5 | 【题目】 请把一段纸条竖着放在桌子上,然后从纸条的下边向 6 | 上方对折1次,压出折痕后展开。此时 折痕是凹下去的,即折痕 7 | 突起的方向指向纸条的背面。如果从纸条的下边向上方连续对折 8 | 2 次,压出折痕后展开,此时有三条折痕,从上到下依次是下折 9 | 痕、下折痕和上折痕。 10 | 给定一 个输入参数N,代表纸条都从下边向上方连续对折N次, 11 | 请从上到下打印所有折痕的方向。 例如:N=1时,打印: down 12 | N=2时,打印: down down up 13 | * 14 | */ 15 | public class Code_05_PaperFolding { 16 | 17 | public static void printAllFolds(int N) { 18 | printProcess(1, N, true); 19 | } 20 | 21 | public static void printProcess(int i, int N, boolean down) { 22 | if (i > N) { 23 | return; 24 | } 25 | printProcess(i + 1, N, true); 26 | System.out.println(down ? "down " : "up "); 27 | printProcess(i + 1, N, false); 28 | } 29 | 30 | public static void main(String[] args) { 31 | int N = 4; 32 | printAllFolds(N); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/GraphGenerator.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | /** 3 | * 4 | * 图的生成 5 | * 6 | */ 7 | public class GraphGenerator { 8 | 9 | public static Graph createGraph(Integer[][] matrix) { 10 | Graph graph = new Graph(); 11 | for (int i = 0; i < matrix.length; i++) {//长度为3的数组 12 | Integer weight = matrix[i][0]; 13 | Integer from = matrix[i][1]; 14 | Integer to = matrix[i][2]; 15 | if (!graph.nodes.containsKey(from)) { 16 | graph.nodes.put(from, new Node(from)); 17 | } 18 | if (!graph.nodes.containsKey(to)) { 19 | graph.nodes.put(to, new Node(to)); 20 | } 21 | Node fromNode = graph.nodes.get(from); 22 | Node toNode = graph.nodes.get(to); 23 | Edge newEdge = new Edge(weight, fromNode, toNode); 24 | fromNode.nexts.add(toNode); 25 | fromNode.out++; 26 | toNode.in++; 27 | fromNode.edges.add(newEdge); 28 | graph.edges.add(newEdge); 29 | } 30 | return graph; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_07/Code_05_LowestLexicography.java: -------------------------------------------------------------------------------- 1 | package class_07; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | /** 6 | * 7 | * 给定一个字符串类型的数组strs,找到一种拼接方式,使得把所 8 | * 有字 符串拼起来之后形成的字符串具有最低的字典序。 9 | * 10 | */ 11 | public class Code_05_LowestLexicography { 12 | 13 | public static class MyComparator implements Comparator { 14 | @Override 15 | public int compare(String a, String b) { 16 | return (a + b).compareTo(b + a); 17 | } 18 | } 19 | 20 | public static String lowestString(String[] strs) { 21 | if (strs == null || strs.length == 0) { 22 | return ""; 23 | } 24 | Arrays.sort(strs, new MyComparator()); 25 | String res = ""; 26 | for (int i = 0; i < strs.length; i++) { 27 | res += strs[i]; 28 | } 29 | return res; 30 | } 31 | 32 | public static void main(String[] args) { 33 | String[] strs1 = { "jibw", "ji", "jp", "bw", "jibw" }; 34 | System.out.println(lowestString(strs1)); 35 | 36 | String[] strs2 = { "ba", "b" }; 37 | System.out.println(lowestString(strs2)); 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_06_ReverseStackUsingRecursive.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | 3 | import java.util.Stack; 4 | /** 5 | * 6 | * 用递归翻转一个栈ReverseStackUsingRecursive 7 | */ 8 | public class Code_06_ReverseStackUsingRecursive { 9 | 10 | public static void reverse(Stack stack) { 11 | if (stack.isEmpty()) { 12 | return; 13 | } 14 | int i = getAndRemoveLastElement(stack); 15 | reverse(stack); 16 | stack.push(i); 17 | } 18 | 19 | public static int getAndRemoveLastElement(Stack stack) { 20 | int result = stack.pop(); 21 | if (stack.isEmpty()) { 22 | return result; 23 | } else { 24 | int last = getAndRemoveLastElement(stack); 25 | stack.push(result); 26 | return last; 27 | } 28 | } 29 | 30 | public static void main(String[] args) { 31 | Stack test = new Stack(); 32 | test.push(1); 33 | test.push(2); 34 | test.push(3); 35 | test.push(4); 36 | test.push(5); 37 | reverse(test); 38 | while (!test.isEmpty()) { 39 | System.out.println(test.pop()); 40 | } 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Code_03_TopologySort.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import java.util.Queue; 8 | /** 9 | * 10 | * 拓扑排序算法 11 | * 适用范围:要求有向图,且有入度为0的节点,且没有环 12 | * 13 | */ 14 | public class Code_03_TopologySort { 15 | 16 | // directed graph and no loop 17 | public static List sortedTopology(Graph graph) { 18 | HashMap inMap = new HashMap<>(); 19 | Queue zeroInQueue = new LinkedList<>(); 20 | for (Node node : graph.nodes.values()) { 21 | inMap.put(node, node.in); 22 | if (node.in == 0) { 23 | zeroInQueue.add(node); 24 | } 25 | } 26 | List result = new ArrayList<>(); 27 | while (!zeroInQueue.isEmpty()) { 28 | Node cur = zeroInQueue.poll(); 29 | result.add(cur); 30 | for (Node next : cur.nexts) { 31 | inMap.put(next, inMap.get(next) - 1); 32 | if (inMap.get(next) == 0) { 33 | zeroInQueue.add(next); 34 | } 35 | } 36 | } 37 | return result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_05_Cow.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * 母牛每年生一只母牛,新出生的母牛成长三年后也能每年生一只 5 | * 母牛,假设不会死。求N年后,母牛的数量。 6 | * fn=f(n-1)+f(n-3) 7 | * 8 | * 如果每只母牛只能活10年,求N年后,母牛的数量 9 | * 10 | */ 11 | public class Code_05_Cow { 12 | 13 | public static int cowNumber1(int n) { 14 | if (n < 1) { 15 | return 0; 16 | } 17 | if (n == 1 || n == 2 || n == 3) { 18 | return n; 19 | } 20 | return cowNumber1(n - 1) + cowNumber1(n - 3); 21 | } 22 | 23 | public static int cowNumber2(int n) { 24 | if (n < 1) { 25 | return 0; 26 | } 27 | if (n == 1 || n == 2 || n == 3) { 28 | return n; 29 | } 30 | int res = 3; 31 | int pre = 2; 32 | int prepre = 1; 33 | int tmp1 = 0; 34 | int tmp2 = 0; 35 | for (int i = 4; i <= n; i++) { 36 | tmp1 = res; 37 | tmp2 = pre; 38 | res = res + prepre; 39 | pre = tmp1; 40 | prepre = tmp2; 41 | } 42 | return res; 43 | } 44 | 45 | public static void main(String[] args) { 46 | int n = 20; 47 | System.out.println(cowNumber1(n)); 48 | System.out.println(cowNumber2(n)); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_07/Code_06_BestArrange.java: -------------------------------------------------------------------------------- 1 | package class_07; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | /** 6 | * 7 | * 一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目 8 | * 的宣讲。 给你每一个项目开始的时间和结束的时间(给你一个数 9 | * 组,里面 是一个个具体的项目),你来安排宣讲的日程,要求会 10 | * 议室进行 的宣讲的场次最多。返回这个最多的宣讲场次。 11 | * 12 | */ 13 | public class Code_06_BestArrange { 14 | 15 | public static class Program { 16 | public int start; 17 | public int end; 18 | 19 | public Program(int start, int end) { 20 | this.start = start; 21 | this.end = end; 22 | } 23 | } 24 | 25 | public static class ProgramComparator implements Comparator { 26 | 27 | @Override 28 | public int compare(Program o1, Program o2) { 29 | return o1.end - o2.end; 30 | } 31 | 32 | } 33 | 34 | public static int bestArrange(Program[] programs, int start) { 35 | Arrays.sort(programs, new ProgramComparator()); 36 | int result = 0; 37 | for (int i = 0; i < programs.length; i++) { 38 | if (start <= programs[i].start) { 39 | result++; 40 | start = programs[i].end; 41 | } 42 | } 43 | return result; 44 | } 45 | 46 | public static void main(String[] args) { 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_09_FindNumInSortedMatrix.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | /** 4 | * 5 | * 在行列都排好序的矩阵中找数 6 | 【题目】 给定一个有N*M的整型矩阵matrix和一个整数K, 7 | * matrix的每一行和每一 列都是排好序的。实现一个函数,判断K 8 | * 是否在matrix中。 例如: 0 1 2 5 2 3 4 7 4 9 | * 4 4 8 5 7 7 9 如果K为7,返回true;如果K为6,返 10 | * 回false。 11 | 【要求】 时间复杂度为O(N+M),额外空间复杂度为O(1)。 12 | * 13 | */ 14 | public class Code_09_FindNumInSortedMatrix { 15 | 16 | public static boolean isContains(int[][] matrix, int K) { 17 | int row = 0; 18 | int col = matrix[0].length - 1; 19 | while (row < matrix.length && col > -1) { 20 | if (matrix[row][col] == K) { 21 | return true; 22 | } else if (matrix[row][col] > K) { 23 | col--; 24 | } else { 25 | row++; 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | public static void main(String[] args) { 32 | int[][] matrix = new int[][] { { 0, 1, 2, 3, 4, 5, 6 },// 0 33 | { 10, 12, 13, 15, 16, 17, 18 },// 1 34 | { 23, 24, 25, 26, 27, 28, 29 },// 2 35 | { 44, 45, 46, 47, 48, 49, 50 },// 3 36 | { 65, 66, 67, 68, 69, 70, 71 },// 4 37 | { 96, 97, 98, 99, 100, 111, 122 },// 5 38 | { 166, 176, 186, 187, 190, 195, 200 },// 6 39 | { 233, 243, 321, 341, 356, 370, 380 } // 7 40 | }; 41 | int K = 233; 42 | System.out.println(isContains(matrix, K)); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Code_05_Prim.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.Comparator; 4 | import java.util.HashSet; 5 | import java.util.PriorityQueue; 6 | import java.util.Set; 7 | /** 8 | * 9 | * prim算法 10 | * 适用范围:要求无向图 11 | * 12 | */ 13 | // undirected graph only 14 | public class Code_05_Prim { 15 | 16 | public static class EdgeComparator implements Comparator { 17 | 18 | @Override 19 | public int compare(Edge o1, Edge o2) { 20 | return o1.weight - o2.weight; 21 | } 22 | 23 | } 24 | 25 | public static Set primMST(Graph graph) { 26 | PriorityQueue priorityQueue = new PriorityQueue<>( 27 | new EdgeComparator()); 28 | HashSet set = new HashSet<>(); 29 | Set result = new HashSet<>(); 30 | for (Node node : graph.nodes.values()) { 31 | if (!set.contains(node)) { 32 | set.add(node); 33 | for (Edge edge : node.edges) { 34 | priorityQueue.add(edge); 35 | } 36 | while (!priorityQueue.isEmpty()) { 37 | Edge edge = priorityQueue.poll(); 38 | Node toNode = edge.to; 39 | if (!set.contains(toNode)) { 40 | set.add(toNode); 41 | result.add(edge); 42 | for (Edge nextEdge : toNode.edges) { 43 | priorityQueue.add(nextEdge); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | return result; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_08_Money_Problem.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * Money_Problem 5 | * 6 | * 给你一个数组arr,和一个整数aim。如果可以任意选择arr中的 7 | * 数字,能不能累加得到aim,返回true或者false 8 | * 9 | */ 10 | public class Code_08_Money_Problem { 11 | 12 | public static boolean money1(int[] arr, int aim) { 13 | return process1(arr, 0, 0, aim); 14 | } 15 | 16 | public static boolean process1(int[] arr, int i, int sum, int aim) { 17 | if (sum == aim) { 18 | return true; 19 | } 20 | // sum != aim 21 | if (i == arr.length) { 22 | return false; 23 | } 24 | return process1(arr, i + 1, sum, aim) || process1(arr, i + 1, sum + arr[i], aim); 25 | } 26 | 27 | public static boolean money2(int[] arr, int aim) { 28 | boolean[][] dp = new boolean[arr.length + 1][aim + 1]; 29 | for (int i = 0; i < dp.length; i++) { 30 | dp[i][aim] = true; 31 | } 32 | for (int i = arr.length - 1; i >= 0; i--) { 33 | for (int j = aim - 1; j >= 0; j--) { 34 | dp[i][j] = dp[i + 1][j]; 35 | if (j + arr[i] <= aim) { 36 | dp[i][j] = dp[i][j] || dp[i + 1][j + arr[i]]; 37 | } 38 | } 39 | } 40 | return dp[0][0]; 41 | } 42 | 43 | public static void main(String[] args) { 44 | int[] arr = { 1, 4, 8 }; 45 | int aim = 12; 46 | System.out.println(money1(arr, aim)); 47 | System.out.println(money2(arr, aim)); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_15_FindOneLessValueIndex.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | /** 3 | * 4 | * 搜索局部最小 5 | * 6 | * 给定无序数组arr, 已知arr中任意连个相邻的数都不相等。 7 | * 写一个函数,只需返回arr中任意一个局部最小出现的位置。 8 | * 9 | */ 10 | public class Code_15_FindOneLessValueIndex { 11 | 12 | public static int getLessIndex(int[] arr) { 13 | if (arr == null || arr.length == 0) { 14 | return -1; // no exist 15 | } 16 | if (arr.length == 1 || arr[0] < arr[1]) { 17 | return 0; 18 | } 19 | if (arr[arr.length - 1] < arr[arr.length - 2]) { 20 | return arr.length - 1; 21 | } 22 | int left = 1; 23 | int right = arr.length - 2; 24 | int mid = 0; 25 | while (left < right) { 26 | mid = (left + right) / 2; 27 | if (arr[mid] > arr[mid - 1]) { 28 | right = mid - 1; 29 | } else if (arr[mid] > arr[mid + 1]) { 30 | left = mid + 1; 31 | } else { 32 | return mid; 33 | } 34 | } 35 | return left; 36 | } 37 | 38 | public static void printArray(int[] arr) { 39 | for (int i = 0; i != arr.length; i++) { 40 | System.out.print(arr[i] + " "); 41 | } 42 | System.out.println(); 43 | } 44 | 45 | public static void main(String[] args) { 46 | int[] arr = { 6, 5, 3, 4, 6, 7, 8 , 6, 5}; 47 | printArray(arr); 48 | int index = getLessIndex(arr); 49 | System.out.println("index: " + index + ", value: " + arr[index]); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_08_ZigZagPrintMatrix.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | /** 3 | * 4 | * “之”字形打印矩阵 5 | * 【题目】 给定一个矩阵matrix,按照“之”字形的方式打印这个矩阵, 6 | * 例如: 1 2 3 4 5 6 7 8 9 10 11 12“之”字形打印的 7 | * 结果为:1,2,5,9,6,3,4,7,10,11,8,12 8 | * 【要求】 额外空间复杂度为O(1 9 | * 10 | */ 11 | public class Code_08_ZigZagPrintMatrix { 12 | 13 | public static void printMatrixZigZag(int[][] matrix) { 14 | int tR = 0; 15 | int tC = 0; 16 | int dR = 0; 17 | int dC = 0; 18 | int endR = matrix.length - 1; 19 | int endC = matrix[0].length - 1; 20 | boolean fromUp = false; 21 | while (tR != endR + 1) { 22 | printLevel(matrix, tR, tC, dR, dC, fromUp); 23 | tR = tC == endC ? tR + 1 : tR; 24 | tC = tC == endC ? tC : tC + 1; 25 | dC = dR == endR ? dC + 1 : dC; 26 | dR = dR == endR ? dR : dR + 1; 27 | fromUp = !fromUp; 28 | } 29 | System.out.println(); 30 | } 31 | 32 | public static void printLevel(int[][] m, int tR, int tC, int dR, int dC, 33 | boolean f) { 34 | if (f) { 35 | while (tR != dR + 1) { 36 | System.out.print(m[tR++][tC--] + " "); 37 | } 38 | } else { 39 | while (dR != tR - 1) { 40 | System.out.print(m[dR--][dC++] + " "); 41 | } 42 | } 43 | } 44 | 45 | public static void main(String[] args) { 46 | int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; 47 | printMatrixZigZag(matrix); 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_08_CompleteTreeNodeNumber.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | /** 3 | * 4 | * 已知一棵完全二叉树,求其节点的个数 5 | * 要求:时间复杂度低于O(N),N为这棵树的节点个数 6 | * 7 | */ 8 | public class Code_08_CompleteTreeNodeNumber { 9 | 10 | public static class Node { 11 | public int value; 12 | public Node left; 13 | public Node right; 14 | 15 | public Node(int data) { 16 | this.value = data; 17 | } 18 | } 19 | 20 | public static int nodeNum(Node head) { 21 | if (head == null) { 22 | return 0; 23 | } 24 | return bs(head, 1, mostLeftLevel(head, 1)); 25 | } 26 | //l为在第几层,h为整个树的层数,h相当于全局变量 27 | public static int bs(Node node, int l, int h) { 28 | if (l == h) { 29 | return 1; 30 | } 31 | if (mostLeftLevel(node.right, l + 1) == h) { 32 | return (1 << (h - l)) + bs(node.right, l + 1, h); 33 | } else { 34 | return (1 << (h - l - 1)) + bs(node.left, l + 1, h); 35 | } 36 | } 37 | 38 | public static int mostLeftLevel(Node node, int level) { 39 | while (node != null) { 40 | level++; 41 | node = node.left; 42 | } 43 | return level - 1; 44 | } 45 | 46 | public static void main(String[] args) { 47 | Node head = new Node(1); 48 | head.left = new Node(2); 49 | head.right = new Node(3); 50 | head.left.left = new Node(4); 51 | head.left.right = new Node(5); 52 | head.right.left = new Node(6); 53 | System.out.println(nodeNum(head)); 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_02/Code_04_Manacher.java: -------------------------------------------------------------------------------- 1 | package basic_class_02; 2 | /** 3 | * 4 | * 给定一个字符串,求出其最长回文子串的长度。 5 | * 6 | */ 7 | public class Code_04_Manacher { 8 | 9 | public static char[] manacherString(String str) { 10 | char[] charArr = str.toCharArray(); 11 | char[] res = new char[str.length() * 2 + 1]; 12 | int index = 0; 13 | for (int i = 0; i != res.length; i++) { 14 | res[i] = (i & 1) == 0 ? '#' : charArr[index++]; 15 | } 16 | return res; 17 | } 18 | 19 | public static int maxLcpsLength(String str) { 20 | if (str == null || str.length() == 0) { 21 | return 0; 22 | } 23 | char[] charArr = manacherString(str); 24 | int[] pArr = new int[charArr.length]; 25 | int index = -1; 26 | int pR = -1; 27 | int max = Integer.MIN_VALUE; 28 | for (int i = 0; i != charArr.length; i++) { 29 | pArr[i] = pR > i ? Math.min(pArr[2 * index - i], pR - i) : 1; 30 | while (i + pArr[i] < charArr.length && i - pArr[i] > -1) { 31 | if (charArr[i + pArr[i]] == charArr[i - pArr[i]]) 32 | pArr[i]++; 33 | else { 34 | break; 35 | } 36 | } 37 | if (i + pArr[i] > pR) { 38 | pR = i + pArr[i]; 39 | index = i; 40 | } 41 | max = Math.max(max, pArr[i]); 42 | } 43 | return max - 1; 44 | } 45 | 46 | public static void main(String[] args) { 47 | String str1 = "abc1234321ab"; 48 | System.out.println(maxLcpsLength(str1)); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_06_IsBalancedTree.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | /** 3 | * 4 | * 判断一棵二叉树是否是平衡二叉树 5 | * 6 | */ 7 | public class Code_06_IsBalancedTree { 8 | 9 | public static class Node { 10 | public int value; 11 | public Node left; 12 | public Node right; 13 | 14 | public Node(int data) { 15 | this.value = data; 16 | } 17 | } 18 | 19 | public static boolean isBalance(Node head) { 20 | boolean[] res = new boolean[1]; 21 | res[0] = true; 22 | getHeight(head, 1, res); 23 | return res[0]; 24 | } 25 | 26 | public static int getHeight(Node head, int level, boolean[] res) { 27 | if (head == null) { 28 | return level; 29 | } 30 | int lH = getHeight(head.left, level + 1, res); 31 | if (!res[0]) { 32 | return level; 33 | } 34 | int rH = getHeight(head.right, level + 1, res); 35 | if (!res[0]) { 36 | return level; 37 | } 38 | if (Math.abs(lH - rH) > 1) { 39 | res[0] = false; 40 | } 41 | return Math.max(lH, rH); 42 | } 43 | 44 | public static void main(String[] args) { 45 | Node head = new Node(1); 46 | head.left = new Node(2); 47 | head.right = new Node(3); 48 | head.left.left = new Node(4); 49 | head.left.right = new Node(5); 50 | head.right.left = new Node(6); 51 | head.right.right = new Node(7); 52 | 53 | System.out.println(isBalance(head)); 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_02/Code_01_KMP.java: -------------------------------------------------------------------------------- 1 | package basic_class_02; 2 | 3 | /** 4 | * 5 | * KMP字符串匹配算法 6 | * 7 | */ 8 | public class Code_01_KMP { 9 | 10 | public static int getIndexOf(String s, String m) { 11 | if (s == null || m == null || m.length() < 1 || s.length() < m.length()) { 12 | return -1; 13 | } 14 | char[] ss = s.toCharArray(); 15 | char[] ms = m.toCharArray(); 16 | int si = 0; 17 | int mi = 0; 18 | int[] next = getNextArray(ms); 19 | while (si < ss.length && mi < ms.length) { 20 | if (ss[si] == ms[mi]) { 21 | si++; 22 | mi++; 23 | } else if (next[mi] == -1) { 24 | si++; 25 | } else { 26 | mi = next[mi]; 27 | } 28 | } 29 | return mi == ms.length ? si - mi : -1; 30 | } 31 | 32 | public static int[] getNextArray(char[] ms) { 33 | if (ms.length == 1) { 34 | return new int[] { -1 }; 35 | } 36 | int[] next = new int[ms.length]; 37 | next[0] = -1; 38 | next[1] = 0; 39 | int pos = 2; 40 | int cn = 0; 41 | while (pos < next.length) { 42 | if (ms[pos - 1] == ms[cn]) { 43 | next[pos++] = ++cn; 44 | } else if (cn > 0) { 45 | cn = next[cn]; 46 | } else { 47 | next[pos++] = 0; 48 | } 49 | } 50 | return next; 51 | } 52 | 53 | public static void main(String[] args) { 54 | String str = "abcabcababaccc"; 55 | String match = "ababa"; 56 | System.out.println(getIndexOf(str, match)); 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_03_Print_All_Subsquences.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | /** 6 | * 7 | * 打印一个字符串的全部子序列,包括空字符串 8 | * 9 | */ 10 | public class Code_03_Print_All_Subsquences { 11 | 12 | public static void printAllSubsquence(String str) { 13 | char[] chs = str.toCharArray(); 14 | process(chs, 0); 15 | } 16 | 17 | public static void process(char[] chs, int i) { 18 | if (i == chs.length) { 19 | System.out.println(String.valueOf(chs)); 20 | return; 21 | } 22 | process(chs, i + 1); 23 | char tmp = chs[i]; 24 | chs[i] = 0; 25 | process(chs, i + 1); 26 | chs[i] = tmp; 27 | } 28 | 29 | public static void function(String str) { 30 | char[] chs = str.toCharArray(); 31 | process(chs, 0, new ArrayList()); 32 | } 33 | 34 | public static void process(char[] chs, int i, List res) { 35 | if(i == chs.length) { 36 | printList(res); 37 | } 38 | List resKeep = copyList(res); 39 | resKeep.add(chs[i]); 40 | process(chs, i+1, resKeep); 41 | List resNoInclude = copyList(res); 42 | process(chs, i+1, resNoInclude); 43 | } 44 | 45 | public static void printList(List res) { 46 | // ...; 47 | } 48 | 49 | public static List copyList(List list){ 50 | return null; 51 | } 52 | 53 | 54 | public static void main(String[] args) { 55 | String test = "abc"; 56 | printAllSubsquence(test); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_09_Knapsack.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * 背包问题(Knapsack problem) 5 | * 6 | * 给定两个数组w和v,两个数组长度相等,w[i]表示第i件商品的 7 | * 重量,v[i]表示第i件商品的价值。 再给定一个整数bag,要求 8 | * 你挑选商品的重量加起来一定不能超 过bag,返回满足这个条件 9 | * 下,你能获得的最大价值。 10 | 11 | */ 12 | public class Code_09_Knapsack { 13 | 14 | public static int maxValue1(int[] c, int[] p, int bag) { 15 | return process1(c, p, 0, 0, bag); 16 | } 17 | 18 | public static int process1(int[] weights, int[] values, int i, int alreadyweight, int bag) { 19 | if (alreadyweight > bag) { 20 | return 0; 21 | } 22 | if (i == weights.length) { 23 | return 0; 24 | } 25 | return Math.max( 26 | 27 | process1(weights, values, i + 1, alreadyweight, bag), 28 | 29 | values[i] + process1(weights, values, i + 1, alreadyweight + weights[i], bag)); 30 | } 31 | 32 | public static int maxValue2(int[] c, int[] p, int bag) { 33 | int[][] dp = new int[c.length + 1][bag + 1]; 34 | for (int i = c.length - 1; i >= 0; i--) { 35 | for (int j = bag; j >= 0; j--) { 36 | dp[i][j] = dp[i + 1][j]; 37 | if (j + c[i] <= bag) { 38 | dp[i][j] = Math.max(dp[i][j], p[i] + dp[i + 1][j + c[i]]); 39 | } 40 | } 41 | } 42 | return dp[0][0]; 43 | } 44 | 45 | public static void main(String[] args) { 46 | int[] c = { 3, 2, 4, 7 }; 47 | int[] p = { 5, 6, 3, 19 }; 48 | int bag = 11; 49 | System.out.println(maxValue1(c, p, bag)); 50 | System.out.println(maxValue2(c, p, bag)); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_06_PrintMatrixSpiralOrder.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | /** 3 | * 4 | * 5 | * 旋转正方形矩阵 6 | * 【题目】 给定一个整型正方形矩阵matrix,请把该矩阵调整成 7 | * 顺时针旋转90度的样子。 8 | * 【要求】 额外空间复杂度为O(1)。 9 | * 10 | */ 11 | public class Code_06_PrintMatrixSpiralOrder { 12 | 13 | public static void spiralOrderPrint(int[][] matrix) { 14 | int tR = 0; 15 | int tC = 0; 16 | int dR = matrix.length - 1; 17 | int dC = matrix[0].length - 1; 18 | while (tR <= dR && tC <= dC) { 19 | printEdge(matrix, tR++, tC++, dR--, dC--); 20 | } 21 | } 22 | 23 | public static void printEdge(int[][] m, int tR, int tC, int dR, int dC) { 24 | if (tR == dR) { 25 | for (int i = tC; i <= dC; i++) { 26 | System.out.print(m[tR][i] + " "); 27 | } 28 | } else if (tC == dC) { 29 | for (int i = tR; i <= dR; i++) { 30 | System.out.print(m[i][tC] + " "); 31 | } 32 | } else { 33 | int curC = tC; 34 | int curR = tR; 35 | while (curC != dC) { 36 | System.out.print(m[tR][curC] + " "); 37 | curC++; 38 | } 39 | while (curR != dR) { 40 | System.out.print(m[curR][dC] + " "); 41 | curR++; 42 | } 43 | while (curC != tC) { 44 | System.out.print(m[dR][curC] + " "); 45 | curC--; 46 | } 47 | while (curR != tR) { 48 | System.out.print(m[curR][tC] + " "); 49 | curR--; 50 | } 51 | } 52 | } 53 | 54 | public static void main(String[] args) { 55 | int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, 56 | { 13, 14, 15, 16 } }; 57 | spiralOrderPrint(matrix); 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_08_NetherlandsFlag.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | /** 3 | * 4 | * 荷兰国旗问题 5 | * 给定一个数组arr,和一个数num,请把小于num的数放在数组的 6 | * 左边,等于num的数放在数组的中间,大于num的数放在数组的右边。 7 | * 要求额外空间复杂度O(1),时间复杂度O(N) 8 | */ 9 | public class Code_08_NetherlandsFlag { 10 | 11 | public static int[] partition(int[] arr, int l, int r, int p) { 12 | int less = l - 1; 13 | int more = r + 1; 14 | while (l < more) { 15 | if (arr[l] < p) { 16 | swap(arr, ++less, l++); 17 | } else if (arr[l] > p) { 18 | swap(arr, --more, l); 19 | } else { 20 | l++; 21 | } 22 | } 23 | return new int[] { less + 1, more - 1 }; 24 | } 25 | 26 | // for test 27 | public static void swap(int[] arr, int i, int j) { 28 | int tmp = arr[i]; 29 | arr[i] = arr[j]; 30 | arr[j] = tmp; 31 | } 32 | 33 | // for test 34 | public static int[] generateArray() { 35 | int[] arr = new int[10]; 36 | for (int i = 0; i < arr.length; i++) { 37 | arr[i] = (int) (Math.random() * 3); 38 | } 39 | return arr; 40 | } 41 | 42 | // for test 43 | public static void printArray(int[] arr) { 44 | if (arr == null) { 45 | return; 46 | } 47 | for (int i = 0; i < arr.length; i++) { 48 | System.out.print(arr[i] + " "); 49 | } 50 | System.out.println(); 51 | } 52 | 53 | public static void main(String[] args) { 54 | int[] test = generateArray(); 55 | 56 | printArray(test); 57 | int[] res = partition(test, 0, test.length - 1, 1); 58 | printArray(test); 59 | System.out.println(res[0]); 60 | System.out.println(res[1]); 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_05_RotateMatrix.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | /** 4 | * 5 | * 转圈打印矩阵 6 | * 【题目】 给定一个整型矩阵matrix,请按照转圈的方式打印它。 7 | * 例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 8 | * 15 16 打印结果为:1,2,3,4,8,12,16,15,14,13,9, 9 | * 5,6,7,11, 10 10 | * 【要求】 额外空间复杂度为O(1)。 11 | * 12 | */ 13 | public class Code_05_RotateMatrix { 14 | 15 | public static void rotate(int[][] matrix) { 16 | int tR = 0; 17 | int tC = 0; 18 | int dR = matrix.length - 1; 19 | int dC = matrix[0].length - 1; 20 | while (tR < dR) { 21 | rotateEdge(matrix, tR++, tC++, dR--, dC--); 22 | } 23 | } 24 | //左上角的行列int tR, int tC 25 | //右下角的行列int dR, int dC 26 | public static void rotateEdge(int[][] m, int tR, int tC, int dR, int dC) { 27 | int times = dC - tC; 28 | int tmp = 0; 29 | for (int i = 0; i != times; i++) { 30 | tmp = m[tR][tC + i]; 31 | m[tR][tC + i] = m[dR - i][tC]; 32 | m[dR - i][tC] = m[dR][dC - i]; 33 | m[dR][dC - i] = m[tR + i][dC]; 34 | m[tR + i][dC] = tmp; 35 | } 36 | } 37 | 38 | public static void printMatrix(int[][] matrix) { 39 | for (int i = 0; i != matrix.length; i++) { 40 | for (int j = 0; j != matrix[0].length; j++) { 41 | System.out.print(matrix[i][j] + " "); 42 | } 43 | System.out.println(); 44 | } 45 | } 46 | 47 | public static void main(String[] args) { 48 | int[][] matrix = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, 49 | { 13, 14, 15, 16 } }; 50 | printMatrix(matrix); 51 | rotate(matrix); 52 | System.out.println("========="); 53 | printMatrix(matrix); 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_10_PrintCommonPart.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | /** 3 | * 4 | * 打印两个有序链表的公共部分 5 | * 【题目】 给定两个有序链表的头指针head1和head2,打印两个 6 | * 链表的公共部分。 7 | */ 8 | public class Code_10_PrintCommonPart { 9 | 10 | public static class Node { 11 | public int value; 12 | public Node next; 13 | public Node(int data) { 14 | this.value = data; 15 | } 16 | } 17 | 18 | public static void printCommonPart(Node head1, Node head2) { 19 | System.out.print("Common Part: "); 20 | while (head1 != null && head2 != null) { 21 | if (head1.value < head2.value) { 22 | head1 = head1.next; 23 | } else if (head1.value > head2.value) { 24 | head2 = head2.next; 25 | } else { 26 | System.out.print(head1.value + " "); 27 | head1 = head1.next; 28 | head2 = head2.next; 29 | } 30 | } 31 | System.out.println(); 32 | } 33 | 34 | public static void printLinkedList(Node node) { 35 | System.out.print("Linked List: "); 36 | while (node != null) { 37 | System.out.print(node.value + " "); 38 | node = node.next; 39 | } 40 | System.out.println(); 41 | } 42 | 43 | public static void main(String[] args) { 44 | Node node1 = new Node(2); 45 | node1.next = new Node(3); 46 | node1.next.next = new Node(5); 47 | node1.next.next.next = new Node(6); 48 | 49 | Node node2 = new Node(1); 50 | node2.next = new Node(2); 51 | node2.next.next = new Node(5); 52 | node2.next.next.next = new Node(7); 53 | node2.next.next.next.next = new Node(8); 54 | 55 | printLinkedList(node1); 56 | printLinkedList(node2); 57 | printCommonPart(node1, node2); 58 | 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_02/Code_02_KMP_ShortestHaveTwice.java: -------------------------------------------------------------------------------- 1 | package basic_class_02; 2 | 3 | /** 4 | * 5 | * 题目: 6 | 给定一个字符串str1, 只能往str1的后面添加字符变成str2。 7 | 要求1: str2必须包含两个str1, 两个str1可以有重合, 但是不 8 | 能以同一个位置开头。 9 | 要求2: str2尽量短 10 | 最终返回str2 11 | * 12 | */ 13 | public class Code_02_KMP_ShortestHaveTwice { 14 | 15 | public static String answer(String str) { 16 | if (str == null || str.length() == 0) { 17 | return ""; 18 | } 19 | char[] chas = str.toCharArray(); 20 | if (chas.length == 1) { 21 | return str + str; 22 | } 23 | if (chas.length == 2) { 24 | return chas[0] == chas[1] ? (str + String.valueOf(chas[0])) : (str + str); 25 | } 26 | int endNext = endNextLength(chas); 27 | return str + str.substring(endNext); 28 | } 29 | 30 | public static int endNextLength(char[] chas) { 31 | int[] next = new int[chas.length + 1]; 32 | next[0] = -1; 33 | next[1] = 0; 34 | int pos = 2; 35 | int cn = 0; 36 | while (pos < next.length) { 37 | if (chas[pos - 1] == chas[cn]) { 38 | next[pos++] = ++cn; 39 | } else if (cn > 0) { 40 | cn = next[cn]; 41 | } else { 42 | next[pos++] = 0; 43 | } 44 | } 45 | return next[next.length - 1]; 46 | } 47 | 48 | public static void main(String[] args) { 49 | String test1 = "a"; 50 | System.out.println(answer(test1)); 51 | 52 | String test2 = "aa"; 53 | System.out.println(answer(test2)); 54 | 55 | String test3 = "ab"; 56 | System.out.println(answer(test3)); 57 | 58 | String test4 = "abcdabcd"; 59 | System.out.println(answer(test4)); 60 | 61 | String test5 = "abracadabra"; 62 | System.out.println(answer(test5)); 63 | 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_02/Code_05_Manacher_ShortestEnd.java: -------------------------------------------------------------------------------- 1 | package basic_class_02; 2 | /** 3 | * 4 | * 问题:给定一个字符串str1,只能往str1的后面添加字符变成str2, 5 | * 要求str2整体都是回文串且最短。 6 | * 7 | */ 8 | public class Code_05_Manacher_ShortestEnd { 9 | 10 | public static char[] manacherString(String str) { 11 | char[] charArr = str.toCharArray(); 12 | char[] res = new char[str.length() * 2 + 1]; 13 | int index = 0; 14 | for (int i = 0; i != res.length; i++) { 15 | res[i] = (i & 1) == 0 ? '#' : charArr[index++]; 16 | } 17 | return res; 18 | } 19 | 20 | public static String shortestEnd(String str) { 21 | if (str == null || str.length() == 0) { 22 | return null; 23 | } 24 | char[] charArr = manacherString(str); 25 | int[] pArr = new int[charArr.length]; 26 | int index = -1; 27 | int pR = -1; 28 | int maxContainsEnd = -1; 29 | for (int i = 0; i != charArr.length; i++) { 30 | pArr[i] = pR > i ? Math.min(pArr[2 * index - i], pR - i) : 1; 31 | while (i + pArr[i] < charArr.length && i - pArr[i] > -1) { 32 | if (charArr[i + pArr[i]] == charArr[i - pArr[i]]) 33 | pArr[i]++; 34 | else { 35 | break; 36 | } 37 | } 38 | if (i + pArr[i] > pR) { 39 | pR = i + pArr[i]; 40 | index = i; 41 | } 42 | if (pR == charArr.length) { 43 | maxContainsEnd = pArr[i]; 44 | break; 45 | } 46 | } 47 | char[] res = new char[str.length() - maxContainsEnd + 1]; 48 | for (int i = 0; i < res.length; i++) { 49 | res[res.length - 1 - i] = charArr[i * 2 + 1]; 50 | } 51 | return String.valueOf(res); 52 | } 53 | 54 | public static void main(String[] args) { 55 | String str2 = "abcd123321"; 56 | System.out.println(shortestEnd(str2)); 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_02_Hanoi.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * 汉诺塔问题 5 | * 打印n层汉诺塔从最左边移动到最右边的全部过程 6 | * 7 | */ 8 | public class Code_02_Hanoi { 9 | 10 | public static void hanoi(int n) { 11 | if (n > 0) { 12 | func(n, n, "left", "mid", "right"); 13 | } 14 | } 15 | 16 | public static void func(int rest, int down, String from, String help, String to) { 17 | if (rest == 1) { 18 | System.out.println("move " + down + " from " + from + " to " + to); 19 | } else { 20 | func(rest - 1, down - 1, from, to, help); 21 | func(1, down, from, help, to); 22 | func(rest - 1, down - 1, help, from, to); 23 | } 24 | } 25 | 26 | public static void moveLeftToRight(int N) { 27 | if (N == 1) { 28 | System.out.println("move 1 from left to right"); 29 | } 30 | moveLeftToMid(N - 1); 31 | System.out.println("move " + N + "from left to right"); 32 | moveMidToRight(N - 1); 33 | } 34 | 35 | public static void moveRightToLeft(int N) { 36 | 37 | } 38 | 39 | public static void moveLeftToMid(int N) { 40 | if (N == 1) { 41 | System.out.println("move 1 from left to mid"); 42 | } 43 | moveLeftToRight(N - 1); 44 | System.out.println("move " + N + "from left to mid"); 45 | moveRightToMid(N - 1); 46 | } 47 | 48 | public static void moveMidToLeft(int N) { 49 | 50 | } 51 | 52 | public static void moveRightToMid(int N) { 53 | 54 | } 55 | 56 | public static void moveMidToRight(int N) { 57 | if (N == 1) { 58 | System.out.println("move 1 from mid to right"); 59 | } 60 | moveMidToLeft(N - 1); 61 | System.out.println("move " + N + "from mid to right"); 62 | moveLeftToRight(N - 1); 63 | } 64 | 65 | public static void main(String[] args) { 66 | int n = 3; 67 | hanoi(n); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_04_Print_All_Permutations.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | 3 | import java.util.HashSet; 4 | /** 5 | * 6 | * 打印一个字符串的全部排列 7 | * 打印一个字符串的全部排列,要求不要出现重复的排列 8 | * 9 | */ 10 | public class Code_04_Print_All_Permutations { 11 | 12 | public static void printAllPermutations1(String str) { 13 | char[] chs = str.toCharArray(); 14 | process1(chs, 0); 15 | } 16 | 17 | public static void process1(char[] chs, int i) { 18 | if (i == chs.length) { 19 | System.out.println(String.valueOf(chs)); 20 | } 21 | for (int j = i; j < chs.length; j++) { 22 | swap(chs, i, j); 23 | process1(chs, i + 1); 24 | //swap(chs, i, j); 25 | } 26 | } 27 | 28 | public static void printAllPermutations2(String str) { 29 | char[] chs = str.toCharArray(); 30 | process2(chs, 0); 31 | } 32 | 33 | public static void process2(char[] chs, int i) { 34 | if (i == chs.length) { 35 | System.out.println(String.valueOf(chs)); 36 | } 37 | HashSet set = new HashSet<>(); 38 | for (int j = i; j < chs.length; j++) { 39 | if (!set.contains(chs[j])) { 40 | set.add(chs[j]); 41 | swap(chs, i, j); 42 | process2(chs, i + 1); 43 | //swap(chs, i, j); 44 | } 45 | } 46 | } 47 | 48 | public static void swap(char[] chs, int i, int j) { 49 | char tmp = chs[i]; 50 | chs[i] = chs[j]; 51 | chs[j] = tmp; 52 | } 53 | 54 | public static void main(String[] args) { 55 | String test1 = "abc"; 56 | printAllPermutations1(test1); 57 | System.out.println("======"); 58 | printAllPermutations2(test1); 59 | System.out.println("======"); 60 | 61 | String test2 = "acc"; 62 | printAllPermutations1(test2); 63 | System.out.println("======"); 64 | printAllPermutations2(test2); 65 | System.out.println("======"); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_05/Code_04_UnionFind.java: -------------------------------------------------------------------------------- 1 | package class_05; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | /** 6 | * 7 | * 并查集结构 8 | * 1)isSameSet 9 | * 10 | * 2)Union 11 | */ 12 | public class Code_04_UnionFind { 13 | 14 | public static class Node { 15 | // whatever you like 16 | } 17 | 18 | public static class UnionFindSet { 19 | public HashMap fatherMap;//Key :child, value : father 20 | public HashMap sizeMap;//某一个节点所在的集合的节点的数量 21 | 22 | public UnionFindSet() { 23 | fatherMap = new HashMap(); 24 | sizeMap = new HashMap(); 25 | } 26 | 27 | public void makeSets(List nodes) { 28 | fatherMap.clear(); 29 | sizeMap.clear(); 30 | for (Node node : nodes) { 31 | fatherMap.put(node, node);//每一个节点自己形成一个集合 32 | sizeMap.put(node, 1); 33 | } 34 | } 35 | //递归实现查找并扁平化 36 | private Node findHead(Node node) { 37 | Node father = fatherMap.get(node); 38 | if (father != node) { 39 | father = findHead(father); 40 | } 41 | fatherMap.put(node, father); 42 | return father; 43 | } 44 | 45 | public boolean isSameSet(Node a, Node b) { 46 | return findHead(a) == findHead(b); 47 | } 48 | 49 | public void union(Node a, Node b) { 50 | if (a == null || b == null) { 51 | return; 52 | } 53 | Node aHead = findHead(a); 54 | Node bHead = findHead(b); 55 | if (aHead != bHead) { 56 | int aSetSize= sizeMap.get(aHead); 57 | int bSetSize = sizeMap.get(bHead); 58 | if (aSetSize <= bSetSize) { 59 | fatherMap.put(aHead, bHead); 60 | sizeMap.put(bHead, aSetSize + bSetSize); 61 | } else { 62 | fatherMap.put(bHead, aHead); 63 | sizeMap.put(aHead, aSetSize + bSetSize); 64 | } 65 | } 66 | } 67 | 68 | } 69 | 70 | public static void main(String[] args) { 71 | 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_07/Code_03_IPO.java: -------------------------------------------------------------------------------- 1 | package class_07; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | /** 6 | * IPO问题 7 | * 8 | * 输入: 9 | * 参数1,正数数组costs 10 | * 参数2,正数数组profits 11 | * 参数3,正数k 12 | * 参数4,正数m 13 | * costs[i]表示i号项目的花费 profits[i]表示i号项目在扣除花 14 | * 费之后还能挣到的钱(利润) k表示你不能并行、只能串行的最多 15 | * 做k个项目 m表示你初始的资金 16 | * 说明:你每做完一个项目,马上获得的收益,可以支持你去做下一个 项目。 17 | * 输出: 你最后获得的最大钱数。 18 | * 19 | */ 20 | public class Code_03_IPO { 21 | public static class Node {//项目 22 | public int p;//收益cost 23 | public int c;//花费profit 24 | 25 | public Node(int p, int c) { 26 | this.p = p; 27 | this.c = c; 28 | } 29 | } 30 | 31 | public static class MinCostComparator implements Comparator { 32 | 33 | @Override 34 | public int compare(Node o1, Node o2) { 35 | return o1.c - o2.c; 36 | } 37 | 38 | } 39 | 40 | public static class MaxProfitComparator implements Comparator { 41 | 42 | @Override 43 | public int compare(Node o1, Node o2) { 44 | return o2.p - o1.p; 45 | } 46 | 47 | } 48 | 49 | public static int findMaximizedCapital(int k, int W, int[] Profits, int[] Capital) { 50 | Node[] nodes = new Node[Profits.length];//所有项目 51 | for (int i = 0; i < Profits.length; i++) { 52 | nodes[i] = new Node(Profits[i], Capital[i]); 53 | } 54 | 55 | PriorityQueue minCostQ = new PriorityQueue<>(new MinCostComparator()); 56 | PriorityQueue maxProfitQ = new PriorityQueue<>(new MaxProfitComparator()); 57 | for (int i = 0; i < nodes.length; i++) { 58 | minCostQ.add(nodes[i]); 59 | } 60 | for (int i = 0; i < k; i++) { 61 | while (!minCostQ.isEmpty() && minCostQ.peek().c <= W) { 62 | maxProfitQ.add(minCostQ.poll()); 63 | } 64 | if (maxProfitQ.isEmpty()) { 65 | return W; 66 | } 67 | W += maxProfitQ.poll().p; 68 | } 69 | return W; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_05/Code_03_Islands.java: -------------------------------------------------------------------------------- 1 | package class_05; 2 | /** 3 | * 4 | * 岛问题 5 | * 6 | * 一个矩阵中只有0和1两种值,每个位置都可以和自己的上、下、左、右 7 | * 四个位置相连,如果有一片1连在一起,这个部分叫做一个岛,求一个 8 | * 矩阵中有多少个岛? 9 | * 举例: 10 | 0 0 1 0 1 0 11 | 1 1 1 0 1 0 12 | 1 0 0 1 0 0 13 | 0 0 0 0 0 0 14 | 这个矩阵中有三个岛。 15 | * 16 | */ 17 | public class Code_03_Islands { 18 | 19 | public static int countIslands(int[][] m) { 20 | if (m == null || m[0] == null) { 21 | return 0; 22 | } 23 | int N = m.length; 24 | int M = m[0].length; 25 | int res = 0; 26 | for (int i = 0; i < N; i++) { 27 | for (int j = 0; j < M; j++) { 28 | if (m[i][j] == 1) { 29 | res++; 30 | infect(m, i, j, N, M); 31 | } 32 | } 33 | } 34 | return res; 35 | } 36 | 37 | public static void infect(int[][] m, int i, int j, int N, int M) { 38 | if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != 1) { 39 | return; 40 | } 41 | m[i][j] = 2; 42 | infect(m, i + 1, j, N, M); 43 | infect(m, i - 1, j, N, M); 44 | infect(m, i, j + 1, N, M); 45 | infect(m, i, j - 1, N, M); 46 | } 47 | 48 | public static void main(String[] args) { 49 | int[][] m1 = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 50 | { 0, 1, 1, 1, 0, 1, 1, 1, 0 }, 51 | { 0, 1, 1, 1, 0, 0, 0, 1, 0 }, 52 | { 0, 1, 1, 0, 0, 0, 0, 0, 0 }, 53 | { 0, 0, 0, 0, 0, 1, 1, 0, 0 }, 54 | { 0, 0, 0, 0, 1, 1, 1, 0, 0 }, 55 | { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; 56 | System.out.println(countIslands(m1)); 57 | 58 | int[][] m2 = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 59 | { 0, 1, 1, 1, 1, 1, 1, 1, 0 }, 60 | { 0, 1, 1, 1, 0, 0, 0, 1, 0 }, 61 | { 0, 1, 1, 0, 0, 0, 1, 1, 0 }, 62 | { 0, 0, 0, 0, 0, 1, 1, 0, 0 }, 63 | { 0, 0, 0, 0, 1, 1, 1, 0, 0 }, 64 | { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; 65 | System.out.println(countIslands(m2)); 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_05/Code_02_RandomPool.java: -------------------------------------------------------------------------------- 1 | package class_05; 2 | 3 | import java.util.HashMap; 4 | /** 5 | * 6 | * 设计RandomPool结构 7 | 【题目】 设计一种结构,在该结构中有如下三个功能: 8 | insert(key):将某个key加入到该结构,做到不重复加入。 9 | delete(key):将原本在结构中的某个key移除。 getRandom(): 10 | 等概率随机返回结构中的任何一个key。 11 | 【要求】 Insert、delete和getRandom方法的时间复杂度都是O(1) 12 | * 13 | */ 14 | public class Code_02_RandomPool { 15 | 16 | public static class Pool { 17 | private HashMap keyIndexMap; 18 | private HashMap indexKeyMap; 19 | private int size; 20 | 21 | public Pool() { 22 | this.keyIndexMap = new HashMap(); 23 | this.indexKeyMap = new HashMap(); 24 | this.size = 0; 25 | } 26 | 27 | public void insert(K key) { 28 | if (!this.keyIndexMap.containsKey(key)) { 29 | this.keyIndexMap.put(key, this.size); 30 | this.indexKeyMap.put(this.size++, key); 31 | } 32 | } 33 | 34 | public void delete(K key) { 35 | if (this.keyIndexMap.containsKey(key)) { 36 | int deleteIndex = this.keyIndexMap.get(key); 37 | int lastIndex = --this.size; 38 | K lastKey = this.indexKeyMap.get(lastIndex); 39 | this.keyIndexMap.put(lastKey, deleteIndex); 40 | this.indexKeyMap.put(deleteIndex, lastKey); 41 | this.keyIndexMap.remove(key); 42 | this.indexKeyMap.remove(lastIndex); 43 | } 44 | } 45 | 46 | public K getRandom() { 47 | if (this.size == 0) { 48 | return null; 49 | } 50 | int randomIndex = (int) (Math.random() * this.size); // 0 ~ size -1 51 | return this.indexKeyMap.get(randomIndex); 52 | } 53 | 54 | } 55 | 56 | public static void main(String[] args) { 57 | Pool pool = new Pool(); 58 | pool.insert("zuo"); 59 | pool.insert("cheng"); 60 | pool.insert("yun"); 61 | System.out.println(pool.getRandom()); 62 | System.out.println(pool.getRandom()); 63 | System.out.println(pool.getRandom()); 64 | System.out.println(pool.getRandom()); 65 | System.out.println(pool.getRandom()); 66 | System.out.println(pool.getRandom()); 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_01_Array_To_Stack_Queue.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | /** 3 | * 4 | * 5 | * 用数组结构实现大小固定的队列和栈 6 | */ 7 | public class Code_01_Array_To_Stack_Queue { 8 | 9 | public static class ArrayStack { 10 | private Integer[] arr; 11 | private Integer size; 12 | 13 | public ArrayStack(int initSize) { 14 | if (initSize < 0) { 15 | throw new IllegalArgumentException("The init size is less than 0"); 16 | } 17 | arr = new Integer[initSize]; 18 | size = 0; 19 | } 20 | 21 | public Integer peek() { 22 | if (size == 0) { 23 | return null; 24 | } 25 | return arr[size - 1]; 26 | } 27 | 28 | public void push(int obj) { 29 | if (size == arr.length) { 30 | throw new ArrayIndexOutOfBoundsException("The queue is full"); 31 | } 32 | arr[size++] = obj; 33 | } 34 | 35 | public Integer pop() { 36 | if (size == 0) { 37 | throw new ArrayIndexOutOfBoundsException("The queue is empty"); 38 | } 39 | return arr[--size]; 40 | } 41 | } 42 | 43 | public static class ArrayQueue { 44 | private Integer[] arr; 45 | private Integer size; 46 | private Integer first; 47 | private Integer last; 48 | 49 | public ArrayQueue(int initSize) { 50 | if (initSize < 0) { 51 | throw new IllegalArgumentException("The init size is less than 0"); 52 | } 53 | arr = new Integer[initSize]; 54 | size = 0; 55 | first = 0; 56 | last = 0; 57 | } 58 | 59 | public Integer peek() { 60 | if (size == 0) { 61 | return null; 62 | } 63 | return arr[first]; 64 | } 65 | 66 | public void push(int obj) { 67 | if (size == arr.length) { 68 | throw new ArrayIndexOutOfBoundsException("The queue is full"); 69 | } 70 | size++; 71 | arr[last] = obj; 72 | last = last == arr.length - 1 ? 0 : last + 1; 73 | } 74 | 75 | public Integer poll() { 76 | if (size == 0) { 77 | throw new ArrayIndexOutOfBoundsException("The queue is empty"); 78 | } 79 | size--; 80 | int tmp = first; 81 | first = first == arr.length - 1 ? 0 : first + 1; 82 | return arr[tmp]; 83 | } 84 | } 85 | 86 | public static void main(String[] args) { 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_02_PrintBinaryTree.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | /** 3 | * 4 | * 福利函数 5 | * 打印整个二叉树 6 | * 7 | */ 8 | public class Code_02_PrintBinaryTree { 9 | 10 | public static class Node { 11 | public int value; 12 | public Node left; 13 | public Node right; 14 | 15 | public Node(int data) { 16 | this.value = data; 17 | } 18 | } 19 | 20 | public static void printTree(Node head) { 21 | System.out.println("Binary Tree:"); 22 | printInOrder(head, 0, "H", 17); 23 | System.out.println(); 24 | } 25 | 26 | public static void printInOrder(Node head, int height, String to, int len) { 27 | if (head == null) { 28 | return; 29 | } 30 | printInOrder(head.right, height + 1, "v", len); 31 | String val = to + head.value + to; 32 | int lenM = val.length(); 33 | int lenL = (len - lenM) / 2; 34 | int lenR = len - lenM - lenL; 35 | val = getSpace(lenL) + val + getSpace(lenR); 36 | System.out.println(getSpace(height * len) + val); 37 | printInOrder(head.left, height + 1, "^", len); 38 | } 39 | 40 | public static String getSpace(int num) { 41 | String space = " "; 42 | StringBuffer buf = new StringBuffer(""); 43 | for (int i = 0; i < num; i++) { 44 | buf.append(space); 45 | } 46 | return buf.toString(); 47 | } 48 | 49 | public static void main(String[] args) { 50 | Node head = new Node(1); 51 | head.left = new Node(-222222222); 52 | head.right = new Node(3); 53 | head.left.left = new Node(Integer.MIN_VALUE); 54 | head.right.left = new Node(55555555); 55 | head.right.right = new Node(66); 56 | head.left.left.right = new Node(777); 57 | printTree(head); 58 | 59 | head = new Node(1); 60 | head.left = new Node(2); 61 | head.right = new Node(3); 62 | head.left.left = new Node(4); 63 | head.right.left = new Node(5); 64 | head.right.right = new Node(6); 65 | head.left.left.right = new Node(7); 66 | printTree(head); 67 | 68 | head = new Node(1); 69 | head.left = new Node(1); 70 | head.right = new Node(1); 71 | head.left.left = new Node(1); 72 | head.right.left = new Node(1); 73 | head.right.right = new Node(1); 74 | head.left.left.right = new Node(1); 75 | printTree(head); 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_08/Code_07_MinPath.java: -------------------------------------------------------------------------------- 1 | package class_08; 2 | /** 3 | * 4 | * 给你一个二维数组,二维数组中的每个数都是正数,要求从左上 5 | * 角走到右下角,每一步只能向右或者向下。沿途经过的数字要累 6 | * 加起来。返回最小的路径和。 7 | * 8 | */ 9 | public class Code_07_MinPath { 10 | 11 | public static int minPath1(int[][] matrix) { 12 | return process1(matrix, matrix.length - 1, matrix[0].length - 1); 13 | } 14 | 15 | public static int process1(int[][] matrix, int i, int j) { 16 | int res = matrix[i][j]; 17 | if (i == 0 && j == 0) { 18 | return res; 19 | } 20 | if (i == 0 && j != 0) { 21 | return res + process1(matrix, i, j - 1); 22 | } 23 | if (i != 0 && j == 0) { 24 | return res + process1(matrix, i - 1, j); 25 | } 26 | return res + Math.min(process1(matrix, i, j - 1), process1(matrix, i - 1, j)); 27 | } 28 | 29 | public static int minPath2(int[][] m) { 30 | if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) { 31 | return 0; 32 | } 33 | int row = m.length; 34 | int col = m[0].length; 35 | int[][] dp = new int[row][col]; 36 | dp[0][0] = m[0][0]; 37 | for (int i = 1; i < row; i++) { 38 | dp[i][0] = dp[i - 1][0] + m[i][0]; 39 | } 40 | for (int j = 1; j < col; j++) { 41 | dp[0][j] = dp[0][j - 1] + m[0][j]; 42 | } 43 | for (int i = 1; i < row; i++) { 44 | for (int j = 1; j < col; j++) { 45 | dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + m[i][j]; 46 | } 47 | } 48 | return dp[row - 1][col - 1]; 49 | } 50 | 51 | // for test 52 | public static int[][] generateRandomMatrix(int rowSize, int colSize) { 53 | if (rowSize < 0 || colSize < 0) { 54 | return null; 55 | } 56 | int[][] result = new int[rowSize][colSize]; 57 | for (int i = 0; i != result.length; i++) { 58 | for (int j = 0; j != result[0].length; j++) { 59 | result[i][j] = (int) (Math.random() * 10); 60 | } 61 | } 62 | return result; 63 | } 64 | 65 | public static void main(String[] args) { 66 | int[][] m = { { 1, 3, 5, 9 }, { 8, 1, 3, 4 }, { 5, 0, 6, 1 }, { 8, 8, 4, 0 } }; 67 | System.out.println(minPath1(m)); 68 | System.out.println(minPath2(m)); 69 | 70 | m = generateRandomMatrix(6, 7); 71 | System.out.println(minPath1(m)); 72 | System.out.println(minPath2(m)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_03_StackAndQueueConvert.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | import java.util.Stack; 6 | /** 7 | * 8 | * 如何仅用队列结构实现栈结构? 9 | * 如何仅用栈结构实现队列结构? 10 | * 11 | */ 12 | public class Code_03_StackAndQueueConvert { 13 | 14 | public static class TwoStacksQueue { 15 | private Stack stackPush; 16 | private Stack stackPop; 17 | 18 | public TwoStacksQueue() { 19 | stackPush = new Stack(); 20 | stackPop = new Stack(); 21 | } 22 | 23 | public void push(int pushInt) { 24 | stackPush.push(pushInt); 25 | } 26 | 27 | public int poll() { 28 | if (stackPop.empty() && stackPush.empty()) { 29 | throw new RuntimeException("Queue is empty!"); 30 | } else if (stackPop.empty()) { 31 | while (!stackPush.empty()) { 32 | stackPop.push(stackPush.pop()); 33 | } 34 | } 35 | return stackPop.pop(); 36 | } 37 | 38 | public int peek() { 39 | if (stackPop.empty() && stackPush.empty()) { 40 | throw new RuntimeException("Queue is empty!"); 41 | } else if (stackPop.empty()) { 42 | while (!stackPush.empty()) { 43 | stackPop.push(stackPush.pop()); 44 | } 45 | } 46 | return stackPop.peek(); 47 | } 48 | } 49 | 50 | public static class TwoQueuesStack { 51 | private Queue queue; 52 | private Queue help; 53 | 54 | public TwoQueuesStack() { 55 | queue = new LinkedList(); 56 | help = new LinkedList(); 57 | } 58 | 59 | public void push(int pushInt) { 60 | queue.add(pushInt); 61 | } 62 | 63 | public int peek() { 64 | if (queue.isEmpty()) { 65 | throw new RuntimeException("Stack is empty!"); 66 | } 67 | while (queue.size() != 1) { 68 | help.add(queue.poll()); 69 | } 70 | int res = queue.poll(); 71 | help.add(res); 72 | swap(); 73 | return res; 74 | } 75 | 76 | public int pop() { 77 | if (queue.isEmpty()) { 78 | throw new RuntimeException("Stack is empty!"); 79 | } 80 | while (queue.size() > 1) { 81 | help.add(queue.poll()); 82 | } 83 | int res = queue.poll(); 84 | swap(); 85 | return res; 86 | } 87 | 88 | private void swap() { 89 | Queue tmp = help; 90 | help = queue; 91 | queue = tmp; 92 | } 93 | 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_09_Comparator.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | /** 6 | * 7 | * 自定义排序规则 8 | * 9 | */ 10 | public class Code_09_Comparator { 11 | 12 | public static class Student { 13 | public String name; 14 | public int id; 15 | public int age; 16 | 17 | public Student(String name, int id, int age) { 18 | this.name = name; 19 | this.id = id; 20 | this.age = age; 21 | } 22 | } 23 | 24 | public static class IdAscendingComparator implements Comparator { 25 | 26 | @Override 27 | public int compare(Student o1, Student o2) { 28 | return o1.id - o2.id; 29 | } 30 | 31 | } 32 | 33 | public static class IdDescendingComparator implements Comparator { 34 | 35 | @Override 36 | public int compare(Student o1, Student o2) { 37 | return o2.id - o1.id; 38 | } 39 | 40 | } 41 | 42 | public static class AgeAscendingComparator implements Comparator { 43 | 44 | @Override 45 | public int compare(Student o1, Student o2) { 46 | return o1.age - o2.age; 47 | } 48 | 49 | } 50 | 51 | public static class AgeDescendingComparator implements Comparator { 52 | 53 | @Override 54 | public int compare(Student o1, Student o2) { 55 | return o2.age - o1.age; 56 | } 57 | 58 | } 59 | 60 | public static void printStudents(Student[] students) { 61 | for (Student student : students) { 62 | System.out.println("Name : " + student.name + ", Id : " + student.id + ", Age : " + student.age); 63 | } 64 | System.out.println("==========================="); 65 | } 66 | 67 | public static void main(String[] args) { 68 | Student student1 = new Student("A", 1, 23); 69 | Student student2 = new Student("B", 2, 21); 70 | Student student3 = new Student("C", 3, 22); 71 | 72 | Student[] students = new Student[] { student3, student2, student1 }; 73 | printStudents(students); 74 | 75 | Arrays.sort(students, new IdAscendingComparator()); 76 | printStudents(students); 77 | 78 | Arrays.sort(students, new IdDescendingComparator()); 79 | printStudents(students); 80 | 81 | Arrays.sort(students, new AgeAscendingComparator()); 82 | printStudents(students); 83 | 84 | Arrays.sort(students, new AgeDescendingComparator()); 85 | printStudents(students); 86 | 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_07/Code_02_Less_Money.java: -------------------------------------------------------------------------------- 1 | package class_07; 2 | 3 | import java.util.Comparator; 4 | import java.util.PriorityQueue; 5 | /** 6 | * 金条切割 7 | * 一块金条切成两半,是需要花费和长度数值一样的铜板的。比如 8 | * 长度为20的 金条,不管切成长度多大的两半,都要花费20个铜 9 | * 板。一群人想整分整块金 条,怎么分最省铜板? 10 | * 例如,给定数组{10,20,30},代表一共三个人,整块金条长度为 11 | * 10+20+30=60. 金条要分成10,20,30三个部分。 如果, 先把长 12 | * 度60的金条分成10和50,花费60 再把长度50的金条分成20和30, 13 | * 花费50 一共花费110铜板。 14 | * 但是如果, 先把长度60的金条分成30和30,花费60 再把长度30 15 | * 金条分成10和20,花费30 一共花费90铜板。 16 | * 输入一个数组,返回分割的最小代价。 17 | * 18 | */ 19 | public class Code_02_Less_Money { 20 | 21 | public static int lessMoney(int[] arr) { 22 | PriorityQueue pQ = new PriorityQueue<>(); 23 | for (int i = 0; i < arr.length; i++) { 24 | pQ.add(arr[i]); 25 | } 26 | int sum = 0; 27 | int cur = 0; 28 | while (pQ.size() > 1) { 29 | cur = pQ.poll() + pQ.poll(); 30 | sum += cur; 31 | pQ.add(cur); 32 | } 33 | return sum; 34 | } 35 | 36 | public static class MinheapComparator implements Comparator { 37 | 38 | @Override 39 | public int compare(Integer o1, Integer o2) { 40 | return o1 - o2; // < 0 o1 < o2 负数 41 | } 42 | 43 | } 44 | 45 | public static class MaxheapComparator implements Comparator { 46 | 47 | @Override 48 | public int compare(Integer o1, Integer o2) { 49 | return o2 - o1; // < o2 < o1 50 | } 51 | 52 | } 53 | 54 | public static void main(String[] args) { 55 | // solution 56 | int[] arr = { 6, 7, 8, 9 }; 57 | System.out.println(lessMoney(arr)); 58 | 59 | int[] arrForHeap = { 3, 5, 2, 7, 0, 1, 6, 4 }; 60 | 61 | // min heap 62 | PriorityQueue minQ1 = new PriorityQueue<>(); 63 | for (int i = 0; i < arrForHeap.length; i++) { 64 | minQ1.add(arrForHeap[i]); 65 | } 66 | while (!minQ1.isEmpty()) { 67 | System.out.print(minQ1.poll() + " "); 68 | } 69 | System.out.println(); 70 | 71 | // min heap use Comparator 72 | PriorityQueue minQ2 = new PriorityQueue<>(new MinheapComparator()); 73 | for (int i = 0; i < arrForHeap.length; i++) { 74 | minQ2.add(arrForHeap[i]); 75 | } 76 | while (!minQ2.isEmpty()) { 77 | System.out.print(minQ2.poll() + " "); 78 | } 79 | System.out.println(); 80 | 81 | // max heap use Comparator 82 | PriorityQueue maxQ = new PriorityQueue<>(new MaxheapComparator()); 83 | for (int i = 0; i < arrForHeap.length; i++) { 84 | maxQ.add(arrForHeap[i]); 85 | } 86 | while (!maxQ.isEmpty()) { 87 | System.out.print(maxQ.poll() + " "); 88 | } 89 | 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_07_ReverseList.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | /** 3 | * 4 | * 反转单向和双向链表 5 | * 【题目】 分别实现反转单向链表和反转双向链表的函数。 6 | * 【要求】 如果链表长度为N,时间复杂度要求为O(N),额外空间 7 | * 复杂度要求为O(1) 8 | */ 9 | public class Code_07_ReverseList { 10 | 11 | public static class Node { 12 | public int value; 13 | public Node next; 14 | 15 | public Node(int data) { 16 | this.value = data; 17 | } 18 | } 19 | 20 | public static Node reverseList(Node head) { 21 | Node pre = null; 22 | Node next = null; 23 | while (head != null) { 24 | next = head.next; 25 | head.next = pre; 26 | pre = head; 27 | head = next; 28 | } 29 | return pre; 30 | } 31 | 32 | public static class DoubleNode { 33 | public int value; 34 | public DoubleNode last; 35 | public DoubleNode next; 36 | 37 | public DoubleNode(int data) { 38 | this.value = data; 39 | } 40 | } 41 | 42 | public static DoubleNode reverseList(DoubleNode head) { 43 | DoubleNode pre = null; 44 | DoubleNode next = null; 45 | while (head != null) { 46 | next = head.next; 47 | head.next = pre; 48 | head.last = next; 49 | pre = head; 50 | head = next; 51 | } 52 | return pre; 53 | } 54 | 55 | public static void printLinkedList(Node head) { 56 | System.out.print("Linked List: "); 57 | while (head != null) { 58 | System.out.print(head.value + " "); 59 | head = head.next; 60 | } 61 | System.out.println(); 62 | } 63 | 64 | public static void printDoubleLinkedList(DoubleNode head) { 65 | System.out.print("Double Linked List: "); 66 | DoubleNode end = null; 67 | while (head != null) { 68 | System.out.print(head.value + " "); 69 | end = head; 70 | head = head.next; 71 | } 72 | System.out.print("| "); 73 | while (end != null) { 74 | System.out.print(end.value + " "); 75 | end = end.last; 76 | } 77 | System.out.println(); 78 | } 79 | 80 | public static void main(String[] args) { 81 | Node head1 = new Node(1); 82 | head1.next = new Node(2); 83 | head1.next.next = new Node(3); 84 | printLinkedList(head1); 85 | head1 = reverseList(head1); 86 | printLinkedList(head1); 87 | 88 | DoubleNode head2 = new DoubleNode(1); 89 | head2.next = new DoubleNode(2); 90 | head2.next.last = head2; 91 | head2.next.next = new DoubleNode(3); 92 | head2.next.next.last = head2.next; 93 | head2.next.next.next = new DoubleNode(4); 94 | head2.next.next.next.last = head2.next.next; 95 | printDoubleLinkedList(head2); 96 | printDoubleLinkedList(reverseList(head2)); 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Code_04_Kruskal.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.PriorityQueue; 8 | import java.util.Set; 9 | /** 10 | * 11 | * kruskal算法 12 | * 适用范围:要求无向图 13 | * 14 | */ 15 | //undirected graph only 16 | public class Code_04_Kruskal { 17 | 18 | // Union-Find Set 19 | public static class UnionFind { 20 | private HashMap fatherMap; 21 | private HashMap rankMap; 22 | 23 | public UnionFind() { 24 | fatherMap = new HashMap(); 25 | rankMap = new HashMap(); 26 | } 27 | 28 | private Node findFather(Node n) { 29 | Node father = fatherMap.get(n); 30 | if (father != n) { 31 | father = findFather(father); 32 | } 33 | fatherMap.put(n, father); 34 | return father; 35 | } 36 | 37 | public void makeSets(Collection nodes) { 38 | fatherMap.clear(); 39 | rankMap.clear(); 40 | for (Node node : nodes) { 41 | fatherMap.put(node, node); 42 | rankMap.put(node, 1); 43 | } 44 | } 45 | 46 | public boolean isSameSet(Node a, Node b) { 47 | return findFather(a) == findFather(b); 48 | } 49 | 50 | public void union(Node a, Node b) { 51 | if (a == null || b == null) { 52 | return; 53 | } 54 | Node aFather = findFather(a); 55 | Node bFather = findFather(b); 56 | if (aFather != bFather) { 57 | int aFrank = rankMap.get(aFather); 58 | int bFrank = rankMap.get(bFather); 59 | if (aFrank <= bFrank) { 60 | fatherMap.put(aFather, bFather); 61 | rankMap.put(bFather, aFrank + bFrank); 62 | } else { 63 | fatherMap.put(bFather, aFather); 64 | rankMap.put(aFather, aFrank + bFrank); 65 | } 66 | } 67 | } 68 | } 69 | 70 | public static class EdgeComparator implements Comparator { 71 | 72 | @Override 73 | public int compare(Edge o1, Edge o2) { 74 | return o1.weight - o2.weight; 75 | } 76 | 77 | } 78 | 79 | public static Set kruskalMST(Graph graph) { 80 | UnionFind unionFind = new UnionFind();//生成一个并查集 81 | unionFind.makeSets(graph.nodes.values()); 82 | //生成一个优先级队列(堆) 83 | PriorityQueue priorityQueue = new PriorityQueue<>(new EdgeComparator()); 84 | for (Edge edge : graph.edges) { 85 | priorityQueue.add(edge); 86 | } 87 | Set result = new HashSet<>(); 88 | while (!priorityQueue.isEmpty()) { 89 | Edge edge = priorityQueue.poll(); 90 | if (!unionFind.isSameSet(edge.from, edge.to)) { 91 | result.add(edge); 92 | unionFind.union(edge.from, edge.to); 93 | } 94 | } 95 | return result; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_02/Code_03_KMP_T1SubtreeEqualsT2.java: -------------------------------------------------------------------------------- 1 | package basic_class_02; 2 | /** 3 | * 4 | * 给定两个二叉树T1和T2, 返回T1的某个子树结构是否与T2的结构相等 5 | * 6 | */ 7 | public class Code_03_KMP_T1SubtreeEqualsT2 { 8 | 9 | public static class Node { 10 | public int value; 11 | public Node left; 12 | public Node right; 13 | 14 | public Node(int data) { 15 | this.value = data; 16 | } 17 | } 18 | 19 | public static boolean isSubtree(Node t1, Node t2) { 20 | String t1Str = serialByPre(t1); 21 | String t2Str = serialByPre(t2); 22 | return getIndexOf(t1Str, t2Str) != -1; 23 | } 24 | 25 | public static String serialByPre(Node head) { 26 | if (head == null) { 27 | return "#!"; 28 | } 29 | String res = head.value + "!"; 30 | res += serialByPre(head.left); 31 | res += serialByPre(head.right); 32 | return res; 33 | } 34 | 35 | // KMP 36 | public static int getIndexOf(String s, String m) { 37 | if (s == null || m == null || m.length() < 1 || s.length() < m.length()) { 38 | return -1; 39 | } 40 | char[] ss = s.toCharArray(); 41 | char[] ms = m.toCharArray(); 42 | int[] nextArr = getNextArray(ms); 43 | int index = 0; 44 | int mi = 0; 45 | while (index < ss.length && mi < ms.length) { 46 | if (ss[index] == ms[mi]) { 47 | index++; 48 | mi++; 49 | } else if (nextArr[mi] == -1) { 50 | index++; 51 | } else { 52 | mi = nextArr[mi]; 53 | } 54 | } 55 | return mi == ms.length ? index - mi : -1; 56 | } 57 | 58 | public static int[] getNextArray(char[] ms) { 59 | if (ms.length == 1) { 60 | return new int[] { -1 }; 61 | } 62 | int[] nextArr = new int[ms.length]; 63 | nextArr[0] = -1; 64 | nextArr[1] = 0; 65 | int pos = 2; 66 | int cn = 0; 67 | while (pos < nextArr.length) { 68 | if (ms[pos - 1] == ms[cn]) { 69 | nextArr[pos++] = ++cn; 70 | } else if (cn > 0) { 71 | cn = nextArr[cn]; 72 | } else { 73 | nextArr[pos++] = 0; 74 | } 75 | } 76 | return nextArr; 77 | } 78 | 79 | public static void main(String[] args) { 80 | Node t1 = new Node(1); 81 | t1.left = new Node(2); 82 | t1.right = new Node(3); 83 | t1.left.left = new Node(4); 84 | t1.left.right = new Node(5); 85 | t1.right.left = new Node(6); 86 | t1.right.right = new Node(7); 87 | t1.left.left.right = new Node(8); 88 | t1.left.right.left = new Node(9); 89 | 90 | Node t2 = new Node(2); 91 | t2.left = new Node(4); 92 | t2.left.right = new Node(8); 93 | t2.right = new Node(5); 94 | t2.right.left = new Node(9); 95 | 96 | System.out.println(isSubtree(t1, t2)); 97 | 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_01_InsertionSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 插入排序的细节讲解与复杂度分析 7 | * 时间复杂度O(N^2),额外空间复杂度O(1) 8 | * 9 | */ 10 | public class Code_01_InsertionSort { 11 | 12 | public static void insertionSort(int[] arr) { 13 | if (arr == null || arr.length < 2) { 14 | return; 15 | } 16 | for (int i = 1; i < arr.length; i++) { 17 | for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) { 18 | swap(arr, j, j + 1); 19 | } 20 | } 21 | } 22 | 23 | public static void swap(int[] arr, int i, int j) { 24 | arr[i] = arr[i] ^ arr[j]; 25 | arr[j] = arr[i] ^ arr[j]; 26 | arr[i] = arr[i] ^ arr[j]; 27 | } 28 | 29 | // for test 30 | public static void comparator(int[] arr) { 31 | Arrays.sort(arr); 32 | } 33 | 34 | // for test 35 | public static int[] generateRandomArray(int maxSize, int maxValue) { 36 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 37 | for (int i = 0; i < arr.length; i++) { 38 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 39 | } 40 | return arr; 41 | } 42 | 43 | // for test 44 | public static int[] copyArray(int[] arr) { 45 | if (arr == null) { 46 | return null; 47 | } 48 | int[] res = new int[arr.length]; 49 | for (int i = 0; i < arr.length; i++) { 50 | res[i] = arr[i]; 51 | } 52 | return res; 53 | } 54 | 55 | // for test 56 | public static boolean isEqual(int[] arr1, int[] arr2) { 57 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 58 | return false; 59 | } 60 | if (arr1 == null && arr2 == null) { 61 | return true; 62 | } 63 | if (arr1.length != arr2.length) { 64 | return false; 65 | } 66 | for (int i = 0; i < arr1.length; i++) { 67 | if (arr1[i] != arr2[i]) { 68 | return false; 69 | } 70 | } 71 | return true; 72 | } 73 | 74 | // for test 75 | public static void printArray(int[] arr) { 76 | if (arr == null) { 77 | return; 78 | } 79 | for (int i = 0; i < arr.length; i++) { 80 | System.out.print(arr[i] + " "); 81 | } 82 | System.out.println(); 83 | } 84 | 85 | // for test 86 | public static void main(String[] args) { 87 | int testTime = 500000; 88 | int maxSize = 100; 89 | int maxValue = 100; 90 | boolean succeed = true; 91 | for (int i = 0; i < testTime; i++) { 92 | int[] arr1 = generateRandomArray(maxSize, maxValue); 93 | int[] arr2 = copyArray(arr1); 94 | insertionSort(arr1); 95 | comparator(arr2); 96 | if (!isEqual(arr1, arr2)) { 97 | succeed = false; 98 | break; 99 | } 100 | } 101 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 102 | 103 | int[] arr = generateRandomArray(maxSize, maxValue); 104 | printArray(arr); 105 | insertionSort(arr); 106 | printArray(arr); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_11_MaxGap.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。 7 | * 8 | */ 9 | public class Code_11_MaxGap { 10 | 11 | public static int maxGap(int[] nums) { 12 | if (nums == null || nums.length < 2) { 13 | return 0; 14 | } 15 | int len = nums.length; 16 | int min = Integer.MAX_VALUE; 17 | int max = Integer.MIN_VALUE; 18 | for (int i = 0; i < len; i++) { 19 | min = Math.min(min, nums[i]); 20 | max = Math.max(max, nums[i]); 21 | } 22 | if (min == max) { 23 | return 0; 24 | } 25 | boolean[] hasNum = new boolean[len + 1]; 26 | int[] maxs = new int[len + 1]; 27 | int[] mins = new int[len + 1]; 28 | int bid = 0; 29 | for (int i = 0; i < len; i++) { 30 | bid = bucket(nums[i], len, min, max); 31 | mins[bid] = hasNum[bid] ? Math.min(mins[bid], nums[i]) : nums[i]; 32 | maxs[bid] = hasNum[bid] ? Math.max(maxs[bid], nums[i]) : nums[i]; 33 | hasNum[bid] = true; 34 | } 35 | int res = 0; 36 | int lastMax = maxs[0]; 37 | int i = 1; 38 | for (; i <= len; i++) { 39 | if (hasNum[i]) { 40 | res = Math.max(res, mins[i] - lastMax); 41 | lastMax = maxs[i]; 42 | } 43 | } 44 | return res; 45 | } 46 | 47 | public static int bucket(long num, long len, long min, long max) { 48 | return (int) ((num - min) * len / (max - min)); 49 | } 50 | 51 | // for test 52 | public static int comparator(int[] nums) { 53 | if (nums == null || nums.length < 2) { 54 | return 0; 55 | } 56 | Arrays.sort(nums); 57 | int gap = Integer.MIN_VALUE; 58 | for (int i = 1; i < nums.length; i++) { 59 | gap = Math.max(nums[i] - nums[i - 1], gap); 60 | } 61 | return gap; 62 | } 63 | 64 | // for test 65 | public static int[] generateRandomArray(int maxSize, int maxValue) { 66 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 67 | for (int i = 0; i < arr.length; i++) { 68 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 69 | } 70 | return arr; 71 | } 72 | 73 | // for test 74 | public static int[] copyArray(int[] arr) { 75 | if (arr == null) { 76 | return null; 77 | } 78 | int[] res = new int[arr.length]; 79 | for (int i = 0; i < arr.length; i++) { 80 | res[i] = arr[i]; 81 | } 82 | return res; 83 | } 84 | 85 | // for test 86 | public static void main(String[] args) { 87 | int testTime = 500000; 88 | int maxSize = 100; 89 | int maxValue = 100; 90 | boolean succeed = true; 91 | for (int i = 0; i < testTime; i++) { 92 | int[] arr1 = generateRandomArray(maxSize, maxValue); 93 | int[] arr2 = copyArray(arr1); 94 | if (maxGap(arr1) != comparator(arr2)) { 95 | succeed = false; 96 | break; 97 | } 98 | } 99 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_02_SelectionSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 选择排序的细节讲解与复杂度分析 7 | * 时间复杂度O(N^2),额外空间复杂度O(1) 8 | * 此排序算法仅用于教学 9 | * 10 | */ 11 | public class Code_02_SelectionSort { 12 | 13 | public static void selectionSort(int[] arr) { 14 | if (arr == null || arr.length < 2) { 15 | return; 16 | } 17 | for (int i = 0; i < arr.length - 1; i++) { 18 | int minIndex = i; 19 | for (int j = i + 1; j < arr.length; j++) { 20 | minIndex = arr[j] < arr[minIndex] ? j : minIndex; 21 | } 22 | swap(arr, i, minIndex); 23 | } 24 | } 25 | 26 | public static void swap(int[] arr, int i, int j) { 27 | int tmp = arr[i]; 28 | arr[i] = arr[j]; 29 | arr[j] = tmp; 30 | } 31 | 32 | // for test 33 | public static void comparator(int[] arr) { 34 | Arrays.sort(arr); 35 | } 36 | 37 | // for test 38 | public static int[] generateRandomArray(int maxSize, int maxValue) { 39 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 40 | for (int i = 0; i < arr.length; i++) { 41 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 42 | } 43 | return arr; 44 | } 45 | 46 | // for test 47 | public static int[] copyArray(int[] arr) { 48 | if (arr == null) { 49 | return null; 50 | } 51 | int[] res = new int[arr.length]; 52 | for (int i = 0; i < arr.length; i++) { 53 | res[i] = arr[i]; 54 | } 55 | return res; 56 | } 57 | 58 | // for test 59 | public static boolean isEqual(int[] arr1, int[] arr2) { 60 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 61 | return false; 62 | } 63 | if (arr1 == null && arr2 == null) { 64 | return true; 65 | } 66 | if (arr1.length != arr2.length) { 67 | return false; 68 | } 69 | for (int i = 0; i < arr1.length; i++) { 70 | if (arr1[i] != arr2[i]) { 71 | return false; 72 | } 73 | } 74 | return true; 75 | } 76 | 77 | // for test 78 | public static void printArray(int[] arr) { 79 | if (arr == null) { 80 | return; 81 | } 82 | for (int i = 0; i < arr.length; i++) { 83 | System.out.print(arr[i] + " "); 84 | } 85 | System.out.println(); 86 | } 87 | 88 | // for test 89 | public static void main(String[] args) { 90 | int testTime = 500000; 91 | int maxSize = 100; 92 | int maxValue = 100; 93 | boolean succeed = true; 94 | for (int i = 0; i < testTime; i++) { 95 | int[] arr1 = generateRandomArray(maxSize, maxValue); 96 | int[] arr2 = copyArray(arr1); 97 | selectionSort(arr1); 98 | comparator(arr2); 99 | if (!isEqual(arr1, arr2)) { 100 | succeed = false; 101 | printArray(arr1); 102 | printArray(arr2); 103 | break; 104 | } 105 | } 106 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 107 | 108 | int[] arr = generateRandomArray(maxSize, maxValue); 109 | printArray(arr); 110 | selectionSort(arr); 111 | printArray(arr); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_06_BucketSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 桶排序 6 | * 1,非基于比较的排序,与被排序的样本的实际数据状况很有关系,所 7 | 以实际中并不经常使用 8 | * 2,时间复杂度O(N),额外空间复杂度O(N) 9 | * 3,稳定的排序 10 | * 11 | */ 12 | public class Code_06_BucketSort { 13 | 14 | // only for 0~200 value 15 | public static void bucketSort(int[] arr) { 16 | if (arr == null || arr.length < 2) { 17 | return; 18 | } 19 | int max = Integer.MIN_VALUE; 20 | for (int i = 0; i < arr.length; i++) { 21 | max = Math.max(max, arr[i]); 22 | } 23 | int[] bucket = new int[max + 1]; 24 | for (int i = 0; i < arr.length; i++) { 25 | bucket[arr[i]]++; 26 | } 27 | int i = 0; 28 | for (int j = 0; j < bucket.length; j++) { 29 | while (bucket[j]-- > 0) { 30 | arr[i++] = j; 31 | } 32 | } 33 | } 34 | 35 | // for test 36 | public static void comparator(int[] arr) { 37 | Arrays.sort(arr); 38 | } 39 | 40 | // for test 41 | public static int[] generateRandomArray(int maxSize, int maxValue) { 42 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 43 | for (int i = 0; i < arr.length; i++) { 44 | arr[i] = (int) ((maxValue + 1) * Math.random()); 45 | } 46 | return arr; 47 | } 48 | 49 | // for test 50 | public static int[] copyArray(int[] arr) { 51 | if (arr == null) { 52 | return null; 53 | } 54 | int[] res = new int[arr.length]; 55 | for (int i = 0; i < arr.length; i++) { 56 | res[i] = arr[i]; 57 | } 58 | return res; 59 | } 60 | 61 | // for test 62 | public static boolean isEqual(int[] arr1, int[] arr2) { 63 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 64 | return false; 65 | } 66 | if (arr1 == null && arr2 == null) { 67 | return true; 68 | } 69 | if (arr1.length != arr2.length) { 70 | return false; 71 | } 72 | for (int i = 0; i < arr1.length; i++) { 73 | if (arr1[i] != arr2[i]) { 74 | return false; 75 | } 76 | } 77 | return true; 78 | } 79 | 80 | // for test 81 | public static void printArray(int[] arr) { 82 | if (arr == null) { 83 | return; 84 | } 85 | for (int i = 0; i < arr.length; i++) { 86 | System.out.print(arr[i] + " "); 87 | } 88 | System.out.println(); 89 | } 90 | 91 | // for test 92 | public static void main(String[] args) { 93 | int testTime = 500000; 94 | int maxSize = 100; 95 | int maxValue = 150; 96 | boolean succeed = true; 97 | for (int i = 0; i < testTime; i++) { 98 | int[] arr1 = generateRandomArray(maxSize, maxValue); 99 | int[] arr2 = copyArray(arr1); 100 | bucketSort(arr1); 101 | comparator(arr2); 102 | if (!isEqual(arr1, arr2)) { 103 | succeed = false; 104 | printArray(arr1); 105 | printArray(arr2); 106 | break; 107 | } 108 | } 109 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 110 | 111 | int[] arr = generateRandomArray(maxSize, maxValue); 112 | printArray(arr); 113 | bucketSort(arr); 114 | printArray(arr); 115 | 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_10_GetAllNotIncluded.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | /** 8 | * 9 | * 已知A、B两个数组,求在B中且不在A中的元素 10 | * 11 | */ 12 | public class Code_10_GetAllNotIncluded { 13 | 14 | public static List GetAllNotIncluded(int[] A, int[] B) { 15 | List res = new ArrayList<>(); 16 | for (int i = 0; i < B.length; i++) { 17 | int l = 0; 18 | int r = A.length - 1; 19 | boolean contains = false; 20 | while (l <= r) { 21 | int mid = l + ((r - l) >> 1); 22 | if (A[mid] == B[i]) { 23 | contains = true; 24 | break; 25 | } 26 | if (A[mid] > B[i]) { 27 | r = mid - 1; 28 | } else { 29 | l = mid + 1; 30 | } 31 | } 32 | if (!contains) { 33 | res.add(B[i]); 34 | } 35 | } 36 | return res; 37 | } 38 | 39 | // for test 40 | public static List comparator(int[] A, int[] B) { 41 | List res = new ArrayList<>(); 42 | for (int i = 0; i < B.length; i++) { 43 | boolean contains = false; 44 | for (int j = 0; j < A.length; j++) { 45 | if (A[j] == B[i]) { 46 | contains = true; 47 | break; 48 | } 49 | } 50 | if (!contains) { 51 | res.add(B[i]); 52 | } 53 | } 54 | return res; 55 | } 56 | 57 | // for test 58 | public static int[] generateRandomArray(int maxSize, int maxValue) { 59 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 60 | for (int i = 0; i < arr.length; i++) { 61 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 62 | } 63 | return arr; 64 | } 65 | 66 | // for test 67 | public static boolean isEqual(List l1, List l2) { 68 | if (l1.size() != l2.size()) { 69 | return false; 70 | } 71 | HashMap map = new HashMap<>(); 72 | for (Integer i : l1) { 73 | if (!map.containsKey(i)) { 74 | map.put(i, 0); 75 | } 76 | map.put(i, map.get(i) + 1); 77 | } 78 | for (Integer i : l2) { 79 | if (!map.containsKey(i)) { 80 | return false; 81 | } 82 | map.put(i, map.get(i) - 1); 83 | if (map.get(i) < 0) { 84 | return false; 85 | } 86 | } 87 | return true; 88 | } 89 | 90 | // for test 91 | public static void main(String[] args) { 92 | int testTime = 300000; 93 | int sortedArrayMaxSize = 300; 94 | int unsortedArrayMaxSize = 10; 95 | int maxValue = 100; 96 | boolean succeed = true; 97 | for (int i = 0; i < testTime; i++) { 98 | int[] A = generateRandomArray(sortedArrayMaxSize, maxValue); 99 | int[] B = generateRandomArray(unsortedArrayMaxSize, maxValue); 100 | Arrays.sort(A); 101 | List res1 = GetAllNotIncluded(A, B); 102 | List res2 = comparator(A, B); 103 | if (!isEqual(res1, res2)) { 104 | succeed = false; 105 | break; 106 | } 107 | } 108 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_02_GetMinStack.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | import java.util.Stack; 4 | /** 5 | * 6 | * 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。 7 | 【要求】 8 | 1.pop、push、getMin操作的时间复杂度都是O(1)。 9 | 2.设计的栈类型可以使用现成的栈结构。 10 | * 11 | */ 12 | public class Code_02_GetMinStack { 13 | public static class MyStack1 { 14 | private Stack stackData; 15 | private Stack stackMin; 16 | 17 | public MyStack1() { 18 | this.stackData = new Stack(); 19 | this.stackMin = new Stack(); 20 | } 21 | 22 | public void push(int newNum) { 23 | if (this.stackMin.isEmpty()) { 24 | this.stackMin.push(newNum); 25 | } else if (newNum <= this.getmin()) { 26 | this.stackMin.push(newNum); 27 | } 28 | this.stackData.push(newNum); 29 | } 30 | 31 | public int pop() { 32 | if (this.stackData.isEmpty()) { 33 | throw new RuntimeException("Your stack is empty."); 34 | } 35 | int value = this.stackData.pop(); 36 | if (value == this.getmin()) { 37 | this.stackMin.pop(); 38 | } 39 | return value; 40 | } 41 | 42 | public int getmin() { 43 | if (this.stackMin.isEmpty()) { 44 | throw new RuntimeException("Your stack is empty."); 45 | } 46 | return this.stackMin.peek(); 47 | } 48 | } 49 | 50 | public static class MyStack2 { 51 | private Stack stackData; 52 | private Stack stackMin; 53 | 54 | public MyStack2() { 55 | this.stackData = new Stack(); 56 | this.stackMin = new Stack(); 57 | } 58 | 59 | public void push(int newNum) { 60 | if (this.stackMin.isEmpty()) { 61 | this.stackMin.push(newNum); 62 | } else if (newNum < this.getmin()) { 63 | this.stackMin.push(newNum); 64 | } else { 65 | int newMin = this.stackMin.peek(); 66 | this.stackMin.push(newMin); 67 | } 68 | this.stackData.push(newNum); 69 | } 70 | 71 | public int pop() { 72 | if (this.stackData.isEmpty()) { 73 | throw new RuntimeException("Your stack is empty."); 74 | } 75 | this.stackMin.pop(); 76 | return this.stackData.pop(); 77 | } 78 | 79 | public int getmin() { 80 | if (this.stackMin.isEmpty()) { 81 | throw new RuntimeException("Your stack is empty."); 82 | } 83 | return this.stackMin.peek(); 84 | } 85 | } 86 | 87 | public static void main(String[] args) { 88 | MyStack1 stack1 = new MyStack1(); 89 | stack1.push(3); 90 | System.out.println(stack1.getmin()); 91 | stack1.push(4); 92 | System.out.println(stack1.getmin()); 93 | stack1.push(1); 94 | System.out.println(stack1.getmin()); 95 | System.out.println(stack1.pop()); 96 | System.out.println(stack1.getmin()); 97 | 98 | System.out.println("============="); 99 | 100 | MyStack1 stack2 = new MyStack1(); 101 | stack2.push(3); 102 | System.out.println(stack2.getmin()); 103 | stack2.push(4); 104 | System.out.println(stack2.getmin()); 105 | stack2.push(1); 106 | System.out.println(stack2.getmin()); 107 | System.out.println(stack2.pop()); 108 | System.out.println(stack2.getmin()); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_00_BubbleSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 冒泡排序细节的讲解与复杂度分析 7 | * 时间复杂度O(N^2),额外空间复杂度O(1) 8 | * 此排序算法仅用于教学 9 | */ 10 | public class Code_00_BubbleSort { 11 | 12 | public static void bubbleSort(int[] arr) { 13 | if (arr == null || arr.length < 2) { 14 | return; 15 | } 16 | for (int e = arr.length - 1; e > 0; e--) { 17 | for (int i = 0; i < e; i++) { 18 | if (arr[i] > arr[i + 1]) { 19 | swap(arr, i, i + 1); 20 | } 21 | } 22 | } 23 | } 24 | //^异或运算 25 | //异或运算有一个特点 26 | //如10^8=2 27 | //但10^8^8=10 28 | public static void swap(int[] arr, int i, int j) { 29 | arr[i] = arr[i] ^ arr[j]; 30 | arr[j] = arr[i] ^ arr[j]; 31 | arr[i] = arr[i] ^ arr[j]; 32 | } 33 | 34 | // for test 35 | public static void comparator(int[] arr) { 36 | Arrays.sort(arr); 37 | } 38 | 39 | // for test 40 | public static int[] generateRandomArray(int maxSize, int maxValue) { 41 | //生成长度随机的数组 42 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 43 | for (int i = 0; i < arr.length; i++) { 44 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 45 | } 46 | return arr; 47 | } 48 | 49 | // for test 50 | public static int[] copyArray(int[] arr) { 51 | if (arr == null) { 52 | return null; 53 | } 54 | int[] res = new int[arr.length]; 55 | for (int i = 0; i < arr.length; i++) { 56 | res[i] = arr[i]; 57 | } 58 | return res; 59 | } 60 | 61 | // for test 62 | public static boolean isEqual(int[] arr1, int[] arr2) { 63 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 64 | return false; 65 | } 66 | if (arr1 == null && arr2 == null) { 67 | return true; 68 | } 69 | if (arr1.length != arr2.length) { 70 | return false; 71 | } 72 | for (int i = 0; i < arr1.length; i++) { 73 | if (arr1[i] != arr2[i]) { 74 | return false; 75 | } 76 | } 77 | return true; 78 | } 79 | 80 | // for test 81 | public static void printArray(int[] arr) { 82 | if (arr == null) { 83 | return; 84 | } 85 | for (int i = 0; i < arr.length; i++) { 86 | System.out.print(arr[i] + " "); 87 | } 88 | System.out.println(); 89 | } 90 | 91 | // for test 92 | public static void main(String[] args) { 93 | int testTime = 500000;//测试次数 94 | int maxSize = 100;//数组长度 95 | int maxValue = 100; 96 | boolean succeed = true; 97 | for (int i = 0; i < testTime; i++) { 98 | int[] arr1 = generateRandomArray(maxSize, maxValue);//产生数组 99 | int[] arr2 = copyArray(arr1);//复制数组 100 | bubbleSort(arr1); 101 | comparator(arr2); 102 | if (!isEqual(arr1, arr2)) { 103 | succeed = false; 104 | break; 105 | } 106 | } 107 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 108 | 109 | int[] arr = generateRandomArray(maxSize, maxValue); 110 | printArray(arr); 111 | bubbleSort(arr); 112 | printArray(arr); 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_03_SuccessorNode.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | /** 3 | * 4 | * 在二叉树中找到一个节点的后继节点 5 | * 该结构比普通二叉树节点结构多了一个指向父节点的parent指针。假 6 | 设有一 棵Node类型的节点组成的二叉树,树中每个节点的parent指针 7 | 都正确地指向 自己的父节点,头节点的parent指向null。只给一个在 8 | 二叉树中的某个节点 node,请实现返回node的后继节点的函数。在二 9 | 叉树的中序遍历的序列中, node的下一个节点叫作node的后继节点。 10 | */ 11 | public class Code_03_SuccessorNode { 12 | 13 | public static class Node { 14 | public int value; 15 | public Node left; 16 | public Node right; 17 | public Node parent; 18 | 19 | public Node(int data) { 20 | this.value = data; 21 | } 22 | } 23 | 24 | public static Node getSuccessorNode(Node node) { 25 | if (node == null) { 26 | return node; 27 | } 28 | if (node.right != null) { 29 | return getLeftMost(node.right); 30 | } else {//右节点非空 31 | Node parent = node.parent; 32 | while (parent != null && parent.left != node) { 33 | node = parent; 34 | parent = node.parent; 35 | } 36 | return parent; 37 | } 38 | } 39 | //右节点为空则找最左节点 40 | public static Node getLeftMost(Node node) { 41 | if (node == null) { 42 | return node; 43 | } 44 | while (node.left != null) { 45 | node = node.left; 46 | } 47 | return node; 48 | } 49 | 50 | public static void main(String[] args) { 51 | Node head = new Node(6); 52 | head.parent = null; 53 | head.left = new Node(3); 54 | head.left.parent = head; 55 | head.left.left = new Node(1); 56 | head.left.left.parent = head.left; 57 | head.left.left.right = new Node(2); 58 | head.left.left.right.parent = head.left.left; 59 | head.left.right = new Node(4); 60 | head.left.right.parent = head.left; 61 | head.left.right.right = new Node(5); 62 | head.left.right.right.parent = head.left.right; 63 | head.right = new Node(9); 64 | head.right.parent = head; 65 | head.right.left = new Node(8); 66 | head.right.left.parent = head.right; 67 | head.right.left.left = new Node(7); 68 | head.right.left.left.parent = head.right.left; 69 | head.right.right = new Node(10); 70 | head.right.right.parent = head.right; 71 | 72 | Node test = head.left.left; 73 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 74 | test = head.left.left.right; 75 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 76 | test = head.left; 77 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 78 | test = head.left.right; 79 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 80 | test = head.left.right.right; 81 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 82 | test = head; 83 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 84 | test = head.right.left.left; 85 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 86 | test = head.right.left; 87 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 88 | test = head.right; 89 | System.out.println(test.value + " next: " + getSuccessorNode(test).value); 90 | test = head.right.right; // 10's next is null 91 | System.out.println(test.value + " next: " + getSuccessorNode(test)); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_05/Code_01_HashMap.java: -------------------------------------------------------------------------------- 1 | package class_05; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map.Entry; 7 | /** 8 | * 9 | * 认识哈希函数和哈希表 10 | * 11 | */ 12 | public class Code_01_HashMap { 13 | 14 | public static void main(String[] args) { 15 | HashMap map = new HashMap<>(); 16 | map.put("zuo", "31"); 17 | 18 | System.out.println(map.containsKey("zuo")); 19 | System.out.println(map.containsKey("chengyun")); 20 | System.out.println("========================="); 21 | 22 | System.out.println(map.get("zuo")); 23 | System.out.println(map.get("chengyun")); 24 | System.out.println("========================="); 25 | 26 | System.out.println(map.isEmpty()); 27 | System.out.println(map.size()); 28 | System.out.println("========================="); 29 | 30 | System.out.println(map.remove("zuo")); 31 | System.out.println(map.containsKey("zuo")); 32 | System.out.println(map.get("zuo")); 33 | System.out.println(map.isEmpty()); 34 | System.out.println(map.size()); 35 | System.out.println("========================="); 36 | 37 | map.put("zuo", "31"); 38 | System.out.println(map.get("zuo")); 39 | map.put("zuo", "32"); 40 | System.out.println(map.get("zuo")); 41 | System.out.println("========================="); 42 | 43 | map.put("zuo", "31"); 44 | map.put("cheng", "32"); 45 | map.put("yun", "33"); 46 | 47 | for (String key : map.keySet()) { 48 | System.out.println(key); 49 | } 50 | System.out.println("========================="); 51 | 52 | for (String values : map.values()) { 53 | System.out.println(values); 54 | } 55 | System.out.println("========================="); 56 | 57 | map.clear(); 58 | map.put("A", "1"); 59 | map.put("B", "2"); 60 | map.put("C", "3"); 61 | map.put("D", "1"); 62 | map.put("E", "2"); 63 | map.put("F", "3"); 64 | map.put("G", "1"); 65 | map.put("H", "2"); 66 | map.put("I", "3"); 67 | for (Entry entry : map.entrySet()) { 68 | String key = entry.getKey(); 69 | String value = entry.getValue(); 70 | System.out.println(key + "," + value); 71 | } 72 | System.out.println("========================="); 73 | 74 | // you can not remove item in map when you use the iterator of map 75 | // for(Entry entry : map.entrySet()){ 76 | // if(!entry.getValue().equals("1")){ 77 | // map.remove(entry.getKey()); 78 | // } 79 | // } 80 | 81 | // if you want to remove items, collect them first, then remove them by 82 | // this way. 83 | List removeKeys = new ArrayList(); 84 | for (Entry entry : map.entrySet()) { 85 | if (!entry.getValue().equals("1")) { 86 | removeKeys.add(entry.getKey()); 87 | } 88 | } 89 | for (String removeKey : removeKeys) { 90 | map.remove(removeKey); 91 | } 92 | for (Entry entry : map.entrySet()) { 93 | String key = entry.getKey(); 94 | String value = entry.getValue(); 95 | System.out.println(key + "," + value); 96 | } 97 | System.out.println("========================="); 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_07/Code_01_TrieTree.java: -------------------------------------------------------------------------------- 1 | package class_07; 2 | /** 3 | * 4 | * 前缀树 5 | * 6 | * 例子: 7 | * 一个字符串类型的数组arr1,另一个字符串类型的数组arr2。 8 | * arr2中有哪些字符,是arr1中出现的?请打印 9 | * arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印 10 | * arr2中有哪些字符,是作为arr1中某个字符串前缀出现的?请打印arr2中出现次数最大的前缀。 11 | * 12 | */ 13 | public class Code_01_TrieTree { 14 | 15 | public static class TrieNode { 16 | public int path; 17 | public int end; 18 | public TrieNode[] nexts; 19 | 20 | public TrieNode() { 21 | path = 0; 22 | end = 0; 23 | nexts = new TrieNode[26];//小写字母26个 24 | } 25 | } 26 | 27 | public static class Trie { 28 | private TrieNode root; 29 | 30 | public Trie() { 31 | root = new TrieNode(); 32 | } 33 | 34 | public void insert(String word) { 35 | if (word == null) { 36 | return; 37 | } 38 | char[] chs = word.toCharArray(); 39 | TrieNode node = root; 40 | int index = 0; 41 | for (int i = 0; i < chs.length; i++) { 42 | index = chs[i] - 'a'; 43 | if (node.nexts[index] == null) { 44 | node.nexts[index] = new TrieNode(); 45 | } 46 | node = node.nexts[index]; 47 | node.path++; 48 | } 49 | node.end++; 50 | } 51 | 52 | public void delete(String word) { 53 | if (search(word) != 0) { 54 | char[] chs = word.toCharArray(); 55 | TrieNode node = root; 56 | int index = 0; 57 | for (int i = 0; i < chs.length; i++) { 58 | index = chs[i] - 'a'; 59 | if (--node.nexts[index].path == 0) { 60 | node.nexts[index] = null; 61 | return; 62 | } 63 | node = node.nexts[index]; 64 | } 65 | node.end--; 66 | } 67 | } 68 | 69 | public int search(String word) { 70 | if (word == null) { 71 | return 0; 72 | } 73 | char[] chs = word.toCharArray(); 74 | TrieNode node = root; 75 | int index = 0; 76 | for (int i = 0; i < chs.length; i++) { 77 | index = chs[i] - 'a'; 78 | if (node.nexts[index] == null) { 79 | return 0; 80 | } 81 | node = node.nexts[index]; 82 | } 83 | return node.end; 84 | } 85 | 86 | public int prefixNumber(String pre) { 87 | if (pre == null) { 88 | return 0; 89 | } 90 | char[] chs = pre.toCharArray(); 91 | TrieNode node = root; 92 | int index = 0; 93 | for (int i = 0; i < chs.length; i++) { 94 | index = chs[i] - 'a'; 95 | if (node.nexts[index] == null) { 96 | return 0; 97 | } 98 | node = node.nexts[index]; 99 | } 100 | return node.path; 101 | } 102 | } 103 | 104 | public static void main(String[] args) { 105 | Trie trie = new Trie(); 106 | System.out.println(trie.search("zuo")); 107 | trie.insert("zuo"); 108 | System.out.println(trie.search("zuo")); 109 | trie.delete("zuo"); 110 | System.out.println(trie.search("zuo")); 111 | trie.insert("zuo"); 112 | trie.insert("zuo"); 113 | trie.delete("zuo"); 114 | System.out.println(trie.search("zuo")); 115 | trie.delete("zuo"); 116 | System.out.println(trie.search("zuo")); 117 | trie.insert("zuoa"); 118 | trie.insert("zuoac"); 119 | trie.insert("zuoab"); 120 | trie.insert("zuoad"); 121 | trie.delete("zuoa"); 122 | System.out.println(trie.search("zuoa")); 123 | System.out.println(trie.prefixNumber("zuo")); 124 | 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_07_IsBSTAndCBT.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | /** 6 | * 7 | * 判断一棵树是否是搜索二叉树 8 | * 判断一棵树是否是完全二叉树 9 | * 10 | */ 11 | public class Code_07_IsBSTAndCBT { 12 | 13 | public static class Node { 14 | public int value; 15 | public Node left; 16 | public Node right; 17 | 18 | public Node(int data) { 19 | this.value = data; 20 | } 21 | } 22 | //判断一棵树是否是搜索二叉树 23 | public static boolean isBST(Node head) { 24 | if (head == null) { 25 | return true; 26 | } 27 | boolean res = true; 28 | Node pre = null; 29 | Node cur1 = head; 30 | Node cur2 = null; 31 | while (cur1 != null) { 32 | cur2 = cur1.left; 33 | if (cur2 != null) { 34 | while (cur2.right != null && cur2.right != cur1) { 35 | cur2 = cur2.right; 36 | } 37 | if (cur2.right == null) { 38 | cur2.right = cur1; 39 | cur1 = cur1.left; 40 | continue; 41 | } else { 42 | cur2.right = null; 43 | } 44 | } 45 | if (pre != null && pre.value > cur1.value) { 46 | res = false; 47 | } 48 | pre = cur1; 49 | cur1 = cur1.right; 50 | } 51 | return res; 52 | } 53 | //判断一棵树是否是完全二叉树 54 | public static boolean isCBT(Node head) { 55 | if (head == null) { 56 | return true; 57 | } 58 | Queue queue = new LinkedList(); 59 | boolean leaf = false; 60 | Node l = null; 61 | Node r = null; 62 | queue.offer(head); 63 | while (!queue.isEmpty()) { 64 | head = queue.poll(); 65 | l = head.left; 66 | r = head.right; 67 | if ((leaf && (l != null || r != null)) || (l == null && r != null)) { 68 | return false; 69 | } 70 | if (l != null) { 71 | queue.offer(l); 72 | } 73 | if (r != null) { 74 | queue.offer(r); 75 | } else { 76 | leaf = true; 77 | } 78 | } 79 | return true; 80 | } 81 | 82 | // for test -- print tree 83 | public static void printTree(Node head) { 84 | System.out.println("Binary Tree:"); 85 | printInOrder(head, 0, "H", 17); 86 | System.out.println(); 87 | } 88 | 89 | public static void printInOrder(Node head, int height, String to, int len) { 90 | if (head == null) { 91 | return; 92 | } 93 | printInOrder(head.right, height + 1, "v", len); 94 | String val = to + head.value + to; 95 | int lenM = val.length(); 96 | int lenL = (len - lenM) / 2; 97 | int lenR = len - lenM - lenL; 98 | val = getSpace(lenL) + val + getSpace(lenR); 99 | System.out.println(getSpace(height * len) + val); 100 | printInOrder(head.left, height + 1, "^", len); 101 | } 102 | 103 | public static String getSpace(int num) { 104 | String space = " "; 105 | StringBuffer buf = new StringBuffer(""); 106 | for (int i = 0; i < num; i++) { 107 | buf.append(space); 108 | } 109 | return buf.toString(); 110 | } 111 | 112 | public static void main(String[] args) { 113 | Node head = new Node(4); 114 | head.left = new Node(2); 115 | head.right = new Node(6); 116 | head.left.left = new Node(1); 117 | head.left.right = new Node(3); 118 | head.right.left = new Node(5); 119 | 120 | printTree(head); 121 | System.out.println(isBST(head)); 122 | System.out.println(isCBT(head)); 123 | 124 | } 125 | } -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_04_QuickSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 随机快速排序的细节和复杂度分析 7 | * 可以用荷兰国旗问题来改进快速排序 8 | * 时间复杂度O(N*logN),额外空间复杂度O(logN) 9 | * 10 | 快速排序可以做到稳定性问题,但是非常难,不需要掌握, 11 | 可以搜“01 stable sort” 12 | */ 13 | public class Code_04_QuickSort { 14 | 15 | public static void quickSort(int[] arr) { 16 | if (arr == null || arr.length < 2) { 17 | return; 18 | } 19 | quickSort(arr, 0, arr.length - 1); 20 | } 21 | 22 | public static void quickSort(int[] arr, int l, int r) { 23 | if (l < r) { 24 | swap(arr, l + (int) (Math.random() * (r - l + 1)), r); 25 | int[] p = partition(arr, l, r); 26 | quickSort(arr, l, p[0] - 1); 27 | quickSort(arr, p[1] + 1, r); 28 | } 29 | } 30 | 31 | public static int[] partition(int[] arr, int l, int r) { 32 | int less = l - 1; 33 | int more = r; 34 | while (l < more) { 35 | if (arr[l] < arr[r]) { 36 | swap(arr, ++less, l++); 37 | } else if (arr[l] > arr[r]) { 38 | swap(arr, --more, l); 39 | } else { 40 | l++; 41 | } 42 | } 43 | swap(arr, more, r); 44 | return new int[] { less + 1, more }; 45 | } 46 | 47 | public static void swap(int[] arr, int i, int j) { 48 | int tmp = arr[i]; 49 | arr[i] = arr[j]; 50 | arr[j] = tmp; 51 | } 52 | 53 | // for test 54 | public static void comparator(int[] arr) { 55 | Arrays.sort(arr); 56 | } 57 | 58 | // for test 59 | public static int[] generateRandomArray(int maxSize, int maxValue) { 60 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 61 | for (int i = 0; i < arr.length; i++) { 62 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 63 | } 64 | return arr; 65 | } 66 | 67 | // for test 68 | public static int[] copyArray(int[] arr) { 69 | if (arr == null) { 70 | return null; 71 | } 72 | int[] res = new int[arr.length]; 73 | for (int i = 0; i < arr.length; i++) { 74 | res[i] = arr[i]; 75 | } 76 | return res; 77 | } 78 | 79 | // for test 80 | public static boolean isEqual(int[] arr1, int[] arr2) { 81 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 82 | return false; 83 | } 84 | if (arr1 == null && arr2 == null) { 85 | return true; 86 | } 87 | if (arr1.length != arr2.length) { 88 | return false; 89 | } 90 | for (int i = 0; i < arr1.length; i++) { 91 | if (arr1[i] != arr2[i]) { 92 | return false; 93 | } 94 | } 95 | return true; 96 | } 97 | 98 | // for test 99 | public static void printArray(int[] arr) { 100 | if (arr == null) { 101 | return; 102 | } 103 | for (int i = 0; i < arr.length; i++) { 104 | System.out.print(arr[i] + " "); 105 | } 106 | System.out.println(); 107 | } 108 | 109 | // for test 110 | public static void main(String[] args) { 111 | int testTime = 500000; 112 | int maxSize = 100; 113 | int maxValue = 100; 114 | boolean succeed = true; 115 | for (int i = 0; i < testTime; i++) { 116 | int[] arr1 = generateRandomArray(maxSize, maxValue); 117 | int[] arr2 = copyArray(arr1); 118 | quickSort(arr1); 119 | comparator(arr2); 120 | if (!isEqual(arr1, arr2)) { 121 | succeed = false; 122 | printArray(arr1); 123 | printArray(arr2); 124 | break; 125 | } 126 | } 127 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 128 | 129 | int[] arr = generateRandomArray(maxSize, maxValue); 130 | printArray(arr); 131 | quickSort(arr); 132 | printArray(arr); 133 | 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_12_SmallSum.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | /** 3 | * 4 | *小和问题 5 | 在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。 6 | 例子: 7 | [1,3,4,2,5] 8 | 1左边比1小的数,没有; 9 | 3左边比3小的数,1; 10 | 4左边比4小的数,1、3; 11 | 2左边比2小的数,1; 12 | 5左边比5小的数,1、3、4、2; 13 | 所以小和为1+1+3+1+1+3+4+2=16 14 | * 15 | */ 16 | public class Code_12_SmallSum { 17 | 18 | public static int smallSum(int[] arr) { 19 | if (arr == null || arr.length < 2) { 20 | return 0; 21 | } 22 | return mergeSort(arr, 0, arr.length - 1); 23 | } 24 | 25 | public static int mergeSort(int[] arr, int l, int r) { 26 | if (l == r) { 27 | return 0; 28 | } 29 | int mid = l + ((r - l) >> 1); 30 | return mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r) + merge(arr, l, mid, r); 31 | } 32 | 33 | public static int merge(int[] arr, int l, int m, int r) { 34 | int[] help = new int[r - l + 1]; 35 | int i = 0; 36 | int p1 = l; 37 | int p2 = m + 1; 38 | int res = 0; 39 | while (p1 <= m && p2 <= r) { 40 | res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0; 41 | help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; 42 | } 43 | while (p1 <= m) { 44 | help[i++] = arr[p1++]; 45 | } 46 | while (p2 <= r) { 47 | help[i++] = arr[p2++]; 48 | } 49 | for (i = 0; i < help.length; i++) { 50 | arr[l + i] = help[i]; 51 | } 52 | return res; 53 | } 54 | 55 | // for test 56 | public static int comparator(int[] arr) { 57 | if (arr == null || arr.length < 2) { 58 | return 0; 59 | } 60 | int res = 0; 61 | for (int i = 1; i < arr.length; i++) { 62 | for (int j = 0; j < i; j++) { 63 | res += arr[j] < arr[i] ? arr[j] : 0; 64 | } 65 | } 66 | return res; 67 | } 68 | 69 | // for test 70 | public static int[] generateRandomArray(int maxSize, int maxValue) { 71 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 72 | for (int i = 0; i < arr.length; i++) { 73 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 74 | } 75 | return arr; 76 | } 77 | 78 | // for test 79 | public static int[] copyArray(int[] arr) { 80 | if (arr == null) { 81 | return null; 82 | } 83 | int[] res = new int[arr.length]; 84 | for (int i = 0; i < arr.length; i++) { 85 | res[i] = arr[i]; 86 | } 87 | return res; 88 | } 89 | 90 | // for test 91 | public static boolean isEqual(int[] arr1, int[] arr2) { 92 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 93 | return false; 94 | } 95 | if (arr1 == null && arr2 == null) { 96 | return true; 97 | } 98 | if (arr1.length != arr2.length) { 99 | return false; 100 | } 101 | for (int i = 0; i < arr1.length; i++) { 102 | if (arr1[i] != arr2[i]) { 103 | return false; 104 | } 105 | } 106 | return true; 107 | } 108 | 109 | // for test 110 | public static void printArray(int[] arr) { 111 | if (arr == null) { 112 | return; 113 | } 114 | for (int i = 0; i < arr.length; i++) { 115 | System.out.print(arr[i] + " "); 116 | } 117 | System.out.println(); 118 | } 119 | 120 | // for test 121 | public static void main(String[] args) { 122 | int testTime = 500000; 123 | int maxSize = 100; 124 | int maxValue = 100; 125 | boolean succeed = true; 126 | for (int i = 0; i < testTime; i++) { 127 | int[] arr1 = generateRandomArray(maxSize, maxValue); 128 | int[] arr2 = copyArray(arr1); 129 | if (smallSum(arr1) != comparator(arr2)) { 130 | succeed = false; 131 | printArray(arr1); 132 | printArray(arr2); 133 | break; 134 | } 135 | } 136 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_03_HeapSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 堆排序的细节和复杂度分析 7 | * 时间复杂度O(N*logN),额外空间复杂度O(1) 8 | * 堆结构非常重要 9 | 1,堆结构的heapInsert与heapify 10 | 2,堆结构的增大和减少 11 | 3,如果只是建立堆的过程,时间复杂度为O(N) 12 | 4,优先级队列结构,就是堆结构 13 | * 14 | */ 15 | public class Code_03_HeapSort { 16 | 17 | public static void heapSort(int[] arr) { 18 | if (arr == null || arr.length < 2) { 19 | return; 20 | } 21 | for (int i = 0; i < arr.length; i++) { 22 | heapInsert(arr, i); 23 | } 24 | int size = arr.length; 25 | swap(arr, 0, --size); 26 | while (size > 0) { 27 | heapify(arr, 0, size); 28 | swap(arr, 0, --size); 29 | } 30 | } 31 | //构建大根堆 32 | public static void heapInsert(int[] arr, int index) { 33 | while (arr[index] > arr[(index - 1) / 2]) { 34 | swap(arr, index, (index - 1) / 2); 35 | index = (index - 1) / 2; 36 | } 37 | } 38 | //某位置变化后堆的调整 39 | public static void heapify(int[] arr, int index, int size) { 40 | int left = index * 2 + 1; 41 | while (left < size) { 42 | int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;//取最大的孩子的下标 43 | largest = arr[largest] > arr[index] ? largest : index; 44 | if (largest == index) { 45 | break; 46 | } 47 | swap(arr, largest, index); 48 | index = largest; 49 | left = index * 2 + 1; 50 | } 51 | } 52 | 53 | public static void swap(int[] arr, int i, int j) { 54 | int tmp = arr[i]; 55 | arr[i] = arr[j]; 56 | arr[j] = tmp; 57 | } 58 | 59 | // for test 60 | public static void comparator(int[] arr) { 61 | Arrays.sort(arr); 62 | } 63 | 64 | // for test 65 | public static int[] generateRandomArray(int maxSize, int maxValue) { 66 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 67 | for (int i = 0; i < arr.length; i++) { 68 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 69 | } 70 | return arr; 71 | } 72 | 73 | // for test 74 | public static int[] copyArray(int[] arr) { 75 | if (arr == null) { 76 | return null; 77 | } 78 | int[] res = new int[arr.length]; 79 | for (int i = 0; i < arr.length; i++) { 80 | res[i] = arr[i]; 81 | } 82 | return res; 83 | } 84 | 85 | // for test 86 | public static boolean isEqual(int[] arr1, int[] arr2) { 87 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 88 | return false; 89 | } 90 | if (arr1 == null && arr2 == null) { 91 | return true; 92 | } 93 | if (arr1.length != arr2.length) { 94 | return false; 95 | } 96 | for (int i = 0; i < arr1.length; i++) { 97 | if (arr1[i] != arr2[i]) { 98 | return false; 99 | } 100 | } 101 | return true; 102 | } 103 | 104 | // for test 105 | public static void printArray(int[] arr) { 106 | if (arr == null) { 107 | return; 108 | } 109 | for (int i = 0; i < arr.length; i++) { 110 | System.out.print(arr[i] + " "); 111 | } 112 | System.out.println(); 113 | } 114 | 115 | // for test 116 | public static void main(String[] args) { 117 | int testTime = 500000; 118 | int maxSize = 100; 119 | int maxValue = 100; 120 | boolean succeed = true; 121 | for (int i = 0; i < testTime; i++) { 122 | int[] arr1 = generateRandomArray(maxSize, maxValue); 123 | int[] arr2 = copyArray(arr1); 124 | heapSort(arr1); 125 | comparator(arr2); 126 | if (!isEqual(arr1, arr2)) { 127 | succeed = false; 128 | break; 129 | } 130 | } 131 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 132 | 133 | int[] arr = generateRandomArray(maxSize, maxValue); 134 | printArray(arr); 135 | heapSort(arr); 136 | printArray(arr); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_07_RadixSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * 6 | * 基数排序 7 | * 8 | */ 9 | public class Code_07_RadixSort { 10 | 11 | // only for no-negative value 12 | public static void radixSort(int[] arr) { 13 | if (arr == null || arr.length < 2) { 14 | return; 15 | } 16 | radixSort(arr, 0, arr.length - 1, maxbits(arr)); 17 | } 18 | 19 | public static int maxbits(int[] arr) { 20 | int max = Integer.MIN_VALUE; 21 | for (int i = 0; i < arr.length; i++) { 22 | max = Math.max(max, arr[i]); 23 | } 24 | int res = 0; 25 | while (max != 0) { 26 | res++; 27 | max /= 10; 28 | } 29 | return res; 30 | } 31 | 32 | public static void radixSort(int[] arr, int begin, int end, int digit) { 33 | final int radix = 10; 34 | int i = 0, j = 0; 35 | int[] count = new int[radix]; 36 | int[] bucket = new int[end - begin + 1]; 37 | for (int d = 1; d <= digit; d++) { 38 | for (i = 0; i < radix; i++) { 39 | count[i] = 0; 40 | } 41 | for (i = begin; i <= end; i++) { 42 | j = getDigit(arr[i], d); 43 | count[j]++; 44 | } 45 | for (i = 1; i < radix; i++) { 46 | count[i] = count[i] + count[i - 1]; 47 | } 48 | for (i = end; i >= begin; i--) { 49 | j = getDigit(arr[i], d); 50 | bucket[count[j] - 1] = arr[i]; 51 | count[j]--; 52 | } 53 | for (i = begin, j = 0; i <= end; i++, j++) { 54 | arr[i] = bucket[j]; 55 | } 56 | } 57 | } 58 | 59 | public static int getDigit(int x, int d) { 60 | return ((x / ((int) Math.pow(10, d - 1))) % 10); 61 | } 62 | 63 | // for test 64 | public static void comparator(int[] arr) { 65 | Arrays.sort(arr); 66 | } 67 | 68 | // for test 69 | public static int[] generateRandomArray(int maxSize, int maxValue) { 70 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 71 | for (int i = 0; i < arr.length; i++) { 72 | arr[i] = (int) ((maxValue + 1) * Math.random()); 73 | } 74 | return arr; 75 | } 76 | 77 | // for test 78 | public static int[] copyArray(int[] arr) { 79 | if (arr == null) { 80 | return null; 81 | } 82 | int[] res = new int[arr.length]; 83 | for (int i = 0; i < arr.length; i++) { 84 | res[i] = arr[i]; 85 | } 86 | return res; 87 | } 88 | 89 | // for test 90 | public static boolean isEqual(int[] arr1, int[] arr2) { 91 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 92 | return false; 93 | } 94 | if (arr1 == null && arr2 == null) { 95 | return true; 96 | } 97 | if (arr1.length != arr2.length) { 98 | return false; 99 | } 100 | for (int i = 0; i < arr1.length; i++) { 101 | if (arr1[i] != arr2[i]) { 102 | return false; 103 | } 104 | } 105 | return true; 106 | } 107 | 108 | // for test 109 | public static void printArray(int[] arr) { 110 | if (arr == null) { 111 | return; 112 | } 113 | for (int i = 0; i < arr.length; i++) { 114 | System.out.print(arr[i] + " "); 115 | } 116 | System.out.println(); 117 | } 118 | 119 | // for test 120 | public static void main(String[] args) { 121 | int testTime = 500000; 122 | int maxSize = 100; 123 | int maxValue = 100000; 124 | boolean succeed = true; 125 | for (int i = 0; i < testTime; i++) { 126 | int[] arr1 = generateRandomArray(maxSize, maxValue); 127 | int[] arr2 = copyArray(arr1); 128 | radixSort(arr1); 129 | comparator(arr2); 130 | if (!isEqual(arr1, arr2)) { 131 | succeed = false; 132 | printArray(arr1); 133 | printArray(arr2); 134 | break; 135 | } 136 | } 137 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 138 | 139 | int[] arr = generateRandomArray(maxSize, maxValue); 140 | printArray(arr); 141 | radixSort(arr); 142 | printArray(arr); 143 | 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_07/Code_04_MadianQuick.java: -------------------------------------------------------------------------------- 1 | package class_07; 2 | 3 | import java.util.Arrays; 4 | import java.util.Comparator; 5 | import java.util.PriorityQueue; 6 | /** 7 | * 8 | * 一个数据流中,随时可以取得中位数 9 | * 10 | */ 11 | public class Code_04_MadianQuick { 12 | 13 | public static class MedianHolder { 14 | private PriorityQueue maxHeap = new PriorityQueue(new MaxHeapComparator()); 15 | private PriorityQueue minHeap = new PriorityQueue(new MinHeapComparator()); 16 | 17 | private void modifyTwoHeapsSize() { 18 | if (this.maxHeap.size() == this.minHeap.size() + 2) { 19 | this.minHeap.add(this.maxHeap.poll()); 20 | } 21 | if (this.minHeap.size() == this.maxHeap.size() + 2) { 22 | this.maxHeap.add(this.minHeap.poll()); 23 | } 24 | } 25 | 26 | public void addNumber(int num) { 27 | if (this.maxHeap.isEmpty()) { 28 | this.maxHeap.add(num); 29 | return; 30 | } 31 | if (this.maxHeap.peek() >= num) { 32 | this.maxHeap.add(num); 33 | } else { 34 | if (this.minHeap.isEmpty()) { 35 | this.minHeap.add(num); 36 | return; 37 | } 38 | if (this.minHeap.peek() > num) { 39 | this.maxHeap.add(num); 40 | } else { 41 | this.minHeap.add(num); 42 | } 43 | } 44 | modifyTwoHeapsSize(); 45 | } 46 | 47 | public Integer getMedian() { 48 | int maxHeapSize = this.maxHeap.size(); 49 | int minHeapSize = this.minHeap.size(); 50 | if (maxHeapSize + minHeapSize == 0) { 51 | return null; 52 | } 53 | Integer maxHeapHead = this.maxHeap.peek(); 54 | Integer minHeapHead = this.minHeap.peek(); 55 | if (((maxHeapSize + minHeapSize) & 1) == 0) { 56 | return (maxHeapHead + minHeapHead) / 2; 57 | } 58 | return maxHeapSize > minHeapSize ? maxHeapHead : minHeapHead; 59 | } 60 | 61 | } 62 | 63 | public static class MaxHeapComparator implements Comparator { 64 | @Override 65 | public int compare(Integer o1, Integer o2) { 66 | if (o2 > o1) { 67 | return 1; 68 | } else { 69 | return -1; 70 | } 71 | } 72 | } 73 | 74 | public static class MinHeapComparator implements Comparator { 75 | @Override 76 | public int compare(Integer o1, Integer o2) { 77 | if (o2 < o1) { 78 | return 1; 79 | } else { 80 | return -1; 81 | } 82 | } 83 | } 84 | 85 | // for test 86 | public static int[] getRandomArray(int maxLen, int maxValue) { 87 | int[] res = new int[(int) (Math.random() * maxLen) + 1]; 88 | for (int i = 0; i != res.length; i++) { 89 | res[i] = (int) (Math.random() * maxValue); 90 | } 91 | return res; 92 | } 93 | 94 | // for test, this method is ineffective but absolutely right 95 | public static int getMedianOfArray(int[] arr) { 96 | int[] newArr = Arrays.copyOf(arr, arr.length); 97 | Arrays.sort(newArr); 98 | int mid = (newArr.length - 1) / 2; 99 | if ((newArr.length & 1) == 0) { 100 | return (newArr[mid] + newArr[mid + 1]) / 2; 101 | } else { 102 | return newArr[mid]; 103 | } 104 | } 105 | 106 | public static void printArray(int[] arr) { 107 | for (int i = 0; i != arr.length; i++) { 108 | System.out.print(arr[i] + " "); 109 | } 110 | System.out.println(); 111 | } 112 | 113 | public static void main(String[] args) { 114 | boolean err = false; 115 | int testTimes = 200000; 116 | for (int i = 0; i != testTimes; i++) { 117 | int len = 30; 118 | int maxValue = 1000; 119 | int[] arr = getRandomArray(len, maxValue); 120 | MedianHolder medianHold = new MedianHolder(); 121 | for (int j = 0; j != arr.length; j++) { 122 | medianHold.addNumber(arr[j]); 123 | } 124 | if (medianHold.getMedian() != getMedianOfArray(arr)) { 125 | err = true; 126 | printArray(arr); 127 | break; 128 | } 129 | } 130 | System.out.println(err ? "Oops..what a fuck!" : "today is a beautiful day^_^"); 131 | 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_13_CopyListWithRandom.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | import java.util.HashMap; 4 | /** 5 | * 6 | * 复制含有随机指针节点的链表 7 | * 8 | 【题目】 一种特殊的链表节点类描述如下: 9 | public class Node { public int value; public Node next; public 10 | Node rand; 11 | public Node(int data) { this.value = data; } 12 | } 13 | Node类中的value是节点值,next指针和正常单链表中next指针的意义 14 | 一 样,都指向下一个节点,rand指针是Node类中新增的指针,这个指 15 | 针可 能指向链表中的任意一个节点,也可能指向null。 给定一个由 16 | Node节点类型组成的无环单链表的头节点head,请实现一个 函数完成 17 | 这个链表中所有结构的复制,并返回复制的新链表的头节点。 进阶: 18 | 不使用额外的数据结构,只用有限几个变量,且在时间复杂度为 O(N) 19 | 内完成原问题要实现的函数。 20 | * 21 | */ 22 | public class Code_13_CopyListWithRandom { 23 | 24 | public static class Node { 25 | public int value; 26 | public Node next; 27 | public Node rand; 28 | 29 | public Node(int data) { 30 | this.value = data; 31 | } 32 | } 33 | 34 | public static Node copyListWithRand1(Node head) { 35 | 36 | HashMap map = new HashMap(); 37 | Node cur = head; 38 | 39 | while (cur != null) { 40 | map.put(cur, new Node(cur.value)); 41 | cur = cur.next; 42 | } 43 | cur = head; 44 | while (cur != null) { 45 | 46 | map.get(cur).next = map.get(cur.next); 47 | map.get(cur).rand = map.get(cur.rand); 48 | cur = cur.next; 49 | } 50 | return map.get(head); 51 | } 52 | 53 | public static Node copyListWithRand2(Node head) { 54 | if (head == null) { 55 | return null; 56 | } 57 | Node cur = head; 58 | Node next = null; 59 | // copy node and link to every node 60 | while (cur != null) { 61 | next = cur.next; 62 | cur.next = new Node(cur.value); 63 | cur.next.next = next; 64 | cur = next; 65 | } 66 | cur = head; 67 | Node curCopy = null; 68 | // set copy node rand 69 | while (cur != null) { 70 | next = cur.next.next; 71 | curCopy = cur.next; 72 | curCopy.rand = cur.rand != null ? cur.rand.next : null; 73 | cur = next; 74 | } 75 | Node res = head.next; 76 | cur = head; 77 | // split 78 | while (cur != null) { 79 | next = cur.next.next; 80 | curCopy = cur.next; 81 | cur.next = next; 82 | curCopy.next = next != null ? next.next : null; 83 | cur = next; 84 | } 85 | return res; 86 | } 87 | 88 | public static void printRandLinkedList(Node head) { 89 | Node cur = head; 90 | System.out.print("order: "); 91 | while (cur != null) { 92 | System.out.print(cur.value + " "); 93 | cur = cur.next; 94 | } 95 | System.out.println(); 96 | cur = head; 97 | System.out.print("rand: "); 98 | while (cur != null) { 99 | System.out.print(cur.rand == null ? "- " : cur.rand.value + " "); 100 | cur = cur.next; 101 | } 102 | System.out.println(); 103 | } 104 | 105 | public static void main(String[] args) { 106 | Node head = null; 107 | Node res1 = null; 108 | Node res2 = null; 109 | printRandLinkedList(head); 110 | res1 = copyListWithRand1(head); 111 | printRandLinkedList(res1); 112 | res2 = copyListWithRand2(head); 113 | printRandLinkedList(res2); 114 | printRandLinkedList(head); 115 | System.out.println("========================="); 116 | 117 | head = new Node(1); 118 | head.next = new Node(2); 119 | head.next.next = new Node(3); 120 | head.next.next.next = new Node(4); 121 | head.next.next.next.next = new Node(5); 122 | head.next.next.next.next.next = new Node(6); 123 | 124 | head.rand = head.next.next.next.next.next; // 1 -> 6 125 | head.next.rand = head.next.next.next.next.next; // 2 -> 6 126 | head.next.next.rand = head.next.next.next.next; // 3 -> 5 127 | head.next.next.next.rand = head.next.next; // 4 -> 3 128 | head.next.next.next.next.rand = null; // 5 -> null 129 | head.next.next.next.next.next.rand = head.next.next.next; // 6 -> 4 130 | 131 | printRandLinkedList(head); 132 | res1 = copyListWithRand1(head); 133 | printRandLinkedList(res1); 134 | res2 = copyListWithRand2(head); 135 | printRandLinkedList(res2); 136 | printRandLinkedList(head); 137 | System.out.println("========================="); 138 | 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_12_SmallerEqualBigger.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | /** 4 | * 5 | * 将单向链表按某值划分成左边小、中间相等、右边大的形式 6 | 【题目】 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个 7 | 整 数pivot。实现一个调整链表的函数,将链表调整为左部分都是值小于 pivot 8 | 的节点,中间部分都是值等于pivot的节点,右部分都是值大于 pivot的节点。 9 | 除这个要求外,对调整后的节点顺序没有更多的要求。 例如:链表9->0->4->5- 10 | >1,pivot=3。 调整后链表可以是1->0->4->9->5,也可以是0->1->9->5->4。总 11 | 之,满 足左部分都是小于3的节点,中间部分都是等于3的节点(本例中这个部 12 | 分为空),右部分都是大于3的节点即可。对某部分内部的节点顺序不做 要求。 13 | 进阶: 在原问题的要求之上再增加如下两个要求。 14 | 在左、中、右三个部分的内部也做顺序要求,要求每部分里的节点从左 到右的 15 | 顺序与原链表中节点的先后次序一致。 例如:链表9->0->4->5->1,pivot=3。 16 | 调整后的链表是0->1->9->4->5。 在满足原问题要求的同时,左部分节点从左到 17 | 右为0、1。在原链表中也 是先出现0,后出现1;中间部分在本例中为空,不再 18 | 讨论;右部分节点 从左到右为9、4、5。在原链表中也是先出现9,然后出现4, 19 | 最后出现5。 20 | 如果链表长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)。 21 | */ 22 | public class Code_12_SmallerEqualBigger { 23 | 24 | public static class Node { 25 | public int value; 26 | public Node next; 27 | 28 | public Node(int data) { 29 | this.value = data; 30 | } 31 | } 32 | 33 | public static Node listPartition1(Node head, int pivot) { 34 | if (head == null) { 35 | return head; 36 | } 37 | Node cur = head; 38 | int i = 0; 39 | while (cur != null) { 40 | i++; 41 | cur = cur.next; 42 | } 43 | Node[] nodeArr = new Node[i]; 44 | i = 0; 45 | cur = head; 46 | for (i = 0; i != nodeArr.length; i++) { 47 | nodeArr[i] = cur; 48 | cur = cur.next; 49 | } 50 | arrPartition(nodeArr, pivot); 51 | for (i = 1; i != nodeArr.length; i++) { 52 | nodeArr[i - 1].next = nodeArr[i]; 53 | } 54 | nodeArr[i - 1].next = null; 55 | return nodeArr[0]; 56 | } 57 | 58 | public static void arrPartition(Node[] nodeArr, int pivot) { 59 | int small = -1; 60 | int big = nodeArr.length; 61 | int index = 0; 62 | while (index != big) { 63 | if (nodeArr[index].value < pivot) { 64 | swap(nodeArr, ++small, index++); 65 | } else if (nodeArr[index].value == pivot) { 66 | index++; 67 | } else { 68 | swap(nodeArr, --big, index); 69 | } 70 | } 71 | } 72 | 73 | public static void swap(Node[] nodeArr, int a, int b) { 74 | Node tmp = nodeArr[a]; 75 | nodeArr[a] = nodeArr[b]; 76 | nodeArr[b] = tmp; 77 | } 78 | 79 | public static Node listPartition2(Node head, int pivot) { 80 | Node sH = null; // small head 81 | Node sT = null; // small tail 82 | Node eH = null; // equal head 83 | Node eT = null; // equal tail 84 | Node bH = null; // big head 85 | Node bT = null; // big tail 86 | Node next = null; // save next node 87 | // every node distributed to three lists 88 | while (head != null) { 89 | next = head.next; 90 | head.next = null; 91 | if (head.value < pivot) { 92 | if (sH == null) { 93 | sH = head; 94 | sT = head; 95 | } else { 96 | sT.next = head; 97 | sT = head; 98 | } 99 | } else if (head.value == pivot) { 100 | if (eH == null) { 101 | eH = head; 102 | eT = head; 103 | } else { 104 | eT.next = head; 105 | eT = head; 106 | } 107 | } else { 108 | if (bH == null) { 109 | bH = head; 110 | bT = head; 111 | } else { 112 | bT.next = head; 113 | bT = head; 114 | } 115 | } 116 | head = next; 117 | } 118 | // small and equal reconnect 119 | if (sT != null) { 120 | sT.next = eH; 121 | eT = eT == null ? sT : eT; 122 | } 123 | // all reconnect 124 | if (eT != null) { 125 | eT.next = bH; 126 | } 127 | return sH != null ? sH : eH != null ? eH : bH; 128 | } 129 | 130 | public static void printLinkedList(Node node) { 131 | System.out.print("Linked List: "); 132 | while (node != null) { 133 | System.out.print(node.value + " "); 134 | node = node.next; 135 | } 136 | System.out.println(); 137 | } 138 | 139 | public static void main(String[] args) { 140 | Node head1 = new Node(7); 141 | head1.next = new Node(9); 142 | head1.next.next = new Node(1); 143 | head1.next.next.next = new Node(8); 144 | head1.next.next.next.next = new Node(5); 145 | head1.next.next.next.next.next = new Node(2); 146 | head1.next.next.next.next.next.next = new Node(5); 147 | printLinkedList(head1); 148 | // head1 = listPartition1(head1, 4); 149 | head1 = listPartition2(head1, 5); 150 | printLinkedList(head1); 151 | 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_04_DogCatQueue.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | /** 6 | * 7 | * 猫狗队列 8 | * 实现一种狗猫队列的结构,要求如下: 用户可以调用add方法将cat类或dog类的 9 | * 实例放入队列中; 用户可以调用pollAll方法,将队列中所有的实例按照进队列 10 | * 的先后顺序依次弹出; 用户可以调用pollDog方法,将队列中dog类的实例按照 11 | * 进队列的先后顺序依次弹出; 用户可以调用pollCat方法,将队列中cat类的实 12 | * 例按照进队列的先后顺序依次弹出; 用户可以调用isEmpty方法,检查队列中是 13 | * 否还有dog或cat的实例; 用户可以调用isDogEmpty方法,检查队列中是否有dog 14 | * 类的实例; 用户可以调用isCatEmpty方法,检查队列中是否有cat类的实例。 15 | * 16 | */ 17 | public class Code_04_DogCatQueue { 18 | 19 | public static class Pet { 20 | private String type; 21 | 22 | public Pet(String type) { 23 | this.type = type; 24 | } 25 | 26 | public String getPetType() { 27 | return this.type; 28 | } 29 | } 30 | 31 | public static class Dog extends Pet { 32 | public Dog() { 33 | super("dog"); 34 | } 35 | } 36 | 37 | public static class Cat extends Pet { 38 | public Cat() { 39 | super("cat"); 40 | } 41 | } 42 | 43 | public static class PetEnterQueue { 44 | private Pet pet; 45 | private long count; 46 | 47 | public PetEnterQueue(Pet pet, long count) { 48 | this.pet = pet; 49 | this.count = count; 50 | } 51 | 52 | public Pet getPet() { 53 | return this.pet; 54 | } 55 | 56 | public long getCount() { 57 | return this.count; 58 | } 59 | 60 | public String getEnterPetType() { 61 | return this.pet.getPetType(); 62 | } 63 | } 64 | 65 | public static class DogCatQueue { 66 | private Queue dogQ; 67 | private Queue catQ; 68 | private long count; 69 | 70 | public DogCatQueue() { 71 | this.dogQ = new LinkedList(); 72 | this.catQ = new LinkedList(); 73 | this.count = 0; 74 | } 75 | 76 | public void add(Pet pet) { 77 | if (pet.getPetType().equals("dog")) { 78 | this.dogQ.add(new PetEnterQueue(pet, this.count++)); 79 | } else if (pet.getPetType().equals("cat")) { 80 | this.catQ.add(new PetEnterQueue(pet, this.count++)); 81 | } else { 82 | throw new RuntimeException("err, not dog or cat"); 83 | } 84 | } 85 | 86 | public Pet pollAll() { 87 | if (!this.dogQ.isEmpty() && !this.catQ.isEmpty()) { 88 | if (this.dogQ.peek().getCount() < this.catQ.peek().getCount()) { 89 | return this.dogQ.poll().getPet(); 90 | } else { 91 | return this.catQ.poll().getPet(); 92 | } 93 | } else if (!this.dogQ.isEmpty()) { 94 | return this.dogQ.poll().getPet(); 95 | } else if (!this.catQ.isEmpty()) { 96 | return this.catQ.poll().getPet(); 97 | } else { 98 | throw new RuntimeException("err, queue is empty!"); 99 | } 100 | } 101 | 102 | public Dog pollDog() { 103 | if (!this.isDogQueueEmpty()) { 104 | return (Dog) this.dogQ.poll().getPet(); 105 | } else { 106 | throw new RuntimeException("Dog queue is empty!"); 107 | } 108 | } 109 | 110 | public Cat pollCat() { 111 | if (!this.isCatQueueEmpty()) { 112 | return (Cat) this.catQ.poll().getPet(); 113 | } else 114 | throw new RuntimeException("Cat queue is empty!"); 115 | } 116 | 117 | public boolean isEmpty() { 118 | return this.dogQ.isEmpty() && this.catQ.isEmpty(); 119 | } 120 | 121 | public boolean isDogQueueEmpty() { 122 | return this.dogQ.isEmpty(); 123 | } 124 | 125 | public boolean isCatQueueEmpty() { 126 | return this.catQ.isEmpty(); 127 | } 128 | 129 | } 130 | 131 | public static void main(String[] args) { 132 | DogCatQueue test = new DogCatQueue(); 133 | 134 | Pet dog1 = new Dog(); 135 | Pet cat1 = new Cat(); 136 | Pet dog2 = new Dog(); 137 | Pet cat2 = new Cat(); 138 | Pet dog3 = new Dog(); 139 | Pet cat3 = new Cat(); 140 | 141 | test.add(dog1); 142 | test.add(cat1); 143 | test.add(dog2); 144 | test.add(cat2); 145 | test.add(dog3); 146 | test.add(cat3); 147 | 148 | test.add(dog1); 149 | test.add(cat1); 150 | test.add(dog2); 151 | test.add(cat2); 152 | test.add(dog3); 153 | test.add(cat3); 154 | 155 | test.add(dog1); 156 | test.add(cat1); 157 | test.add(dog2); 158 | test.add(cat2); 159 | test.add(dog3); 160 | test.add(cat3); 161 | while (!test.isDogQueueEmpty()) { 162 | System.out.println(test.pollDog().getPetType()); 163 | } 164 | while (!test.isEmpty()) { 165 | System.out.println(test.pollAll().getPetType()); 166 | } 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_01_PreInPosTraversal.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | 3 | import java.util.Stack; 4 | /** 5 | * 6 | * 实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式 7 | * 8 | */ 9 | public class Code_01_PreInPosTraversal { 10 | 11 | public static class Node { 12 | public int value; 13 | public Node left; 14 | public Node right; 15 | 16 | public Node(int data) { 17 | this.value = data; 18 | } 19 | } 20 | //递归方式先序 21 | public static void preOrderRecur(Node head) { 22 | if (head == null) { 23 | return; 24 | } 25 | System.out.print(head.value + " "); 26 | preOrderRecur(head.left); 27 | preOrderRecur(head.right); 28 | } 29 | //递归方式中序 30 | public static void inOrderRecur(Node head) { 31 | if (head == null) { 32 | return; 33 | } 34 | inOrderRecur(head.left); 35 | System.out.print(head.value + " "); 36 | inOrderRecur(head.right); 37 | } 38 | //递归方式后序 39 | public static void posOrderRecur(Node head) { 40 | if (head == null) { 41 | return; 42 | } 43 | posOrderRecur(head.left); 44 | posOrderRecur(head.right); 45 | System.out.print(head.value + " "); 46 | } 47 | //非递归方式先序遍历 48 | public static void preOrderUnRecur(Node head) { 49 | System.out.print("pre-order: "); 50 | if (head != null) { 51 | Stack stack = new Stack(); 52 | stack.add(head); 53 | while (!stack.isEmpty()) { 54 | head = stack.pop(); 55 | System.out.print(head.value + " "); 56 | if (head.right != null) { 57 | stack.push(head.right); 58 | } 59 | if (head.left != null) { 60 | stack.push(head.left); 61 | } 62 | } 63 | } 64 | System.out.println(); 65 | } 66 | //非递归方式中序遍历 67 | public static void inOrderUnRecur(Node head) { 68 | System.out.print("in-order: "); 69 | if (head != null) { 70 | Stack stack = new Stack(); 71 | while (!stack.isEmpty() || head != null) { 72 | if (head != null) { 73 | stack.push(head); 74 | head = head.left; 75 | } else { 76 | head = stack.pop(); 77 | System.out.print(head.value + " "); 78 | head = head.right; 79 | } 80 | } 81 | } 82 | System.out.println(); 83 | } 84 | //非递归方式后序遍历(双栈实现) 85 | public static void posOrderUnRecur1(Node head) { 86 | System.out.print("pos-order: "); 87 | if (head != null) { 88 | Stack s1 = new Stack(); 89 | Stack s2 = new Stack(); 90 | s1.push(head); 91 | while (!s1.isEmpty()) { 92 | head = s1.pop(); 93 | s2.push(head); 94 | if (head.left != null) { 95 | s1.push(head.left); 96 | } 97 | if (head.right != null) { 98 | s1.push(head.right); 99 | } 100 | } 101 | while (!s2.isEmpty()) { 102 | System.out.print(s2.pop().value + " "); 103 | } 104 | } 105 | System.out.println(); 106 | } 107 | //炫技版后序遍历非递归 108 | public static void posOrderUnRecur2(Node h) { 109 | System.out.print("pos-order: "); 110 | if (h != null) { 111 | Stack stack = new Stack(); 112 | stack.push(h); 113 | Node c = null; 114 | while (!stack.isEmpty()) { 115 | c = stack.peek(); 116 | if (c.left != null && h != c.left && h != c.right) { 117 | stack.push(c.left); 118 | } else if (c.right != null && h != c.right) { 119 | stack.push(c.right); 120 | } else { 121 | System.out.print(stack.pop().value + " "); 122 | h = c; 123 | } 124 | } 125 | } 126 | System.out.println(); 127 | } 128 | 129 | public static void main(String[] args) { 130 | Node head = new Node(5); 131 | head.left = new Node(3); 132 | head.right = new Node(8); 133 | head.left.left = new Node(2); 134 | head.left.right = new Node(4); 135 | head.left.left.left = new Node(1); 136 | head.right.left = new Node(7); 137 | head.right.left.left = new Node(6); 138 | head.right.right = new Node(10); 139 | head.right.right.left = new Node(9); 140 | head.right.right.right = new Node(11); 141 | 142 | // recursive 143 | System.out.println("==============recursive=============="); 144 | System.out.print("pre-order: "); 145 | preOrderRecur(head); 146 | System.out.println(); 147 | System.out.print("in-order: "); 148 | inOrderRecur(head); 149 | System.out.println(); 150 | System.out.print("pos-order: "); 151 | posOrderRecur(head); 152 | System.out.println(); 153 | 154 | // unrecursive 155 | System.out.println("============unrecursive============="); 156 | preOrderUnRecur(head); 157 | inOrderUnRecur(head); 158 | posOrderUnRecur1(head); 159 | posOrderUnRecur2(head); 160 | 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_06/Code_06_Dijkstra.java: -------------------------------------------------------------------------------- 1 | package class_06; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import java.util.Map.Entry; 6 | /** 7 | * 8 | * Dijkstra算法 9 | * 适用范围:没有权值为负数的边 10 | * 11 | */ 12 | // no negative weight 13 | public class Code_06_Dijkstra { 14 | 15 | public static HashMap dijkstra1(Node head) { 16 | HashMap distanceMap = new HashMap<>(); 17 | distanceMap.put(head, 0); 18 | HashSet selectedNodes = new HashSet<>(); 19 | 20 | Node minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); 21 | while (minNode != null) { 22 | int distance = distanceMap.get(minNode); 23 | for (Edge edge : minNode.edges) { 24 | Node toNode = edge.to; 25 | if (!distanceMap.containsKey(toNode)) { 26 | distanceMap.put(toNode, distance + edge.weight); 27 | } 28 | distanceMap.put(edge.to, Math.min(distanceMap.get(toNode), distance + edge.weight)); 29 | } 30 | selectedNodes.add(minNode); 31 | minNode = getMinDistanceAndUnselectedNode(distanceMap, selectedNodes); 32 | } 33 | return distanceMap; 34 | } 35 | 36 | public static Node getMinDistanceAndUnselectedNode(HashMap distanceMap, 37 | HashSet touchedNodes) { 38 | Node minNode = null; 39 | int minDistance = Integer.MAX_VALUE; 40 | for (Entry entry : distanceMap.entrySet()) { 41 | Node node = entry.getKey(); 42 | int distance = entry.getValue(); 43 | if (!touchedNodes.contains(node) && distance < minDistance) { 44 | minNode = node; 45 | minDistance = distance; 46 | } 47 | } 48 | return minNode; 49 | } 50 | 51 | public static class NodeRecord { 52 | public Node node; 53 | public int distance; 54 | 55 | public NodeRecord(Node node, int distance) { 56 | this.node = node; 57 | this.distance = distance; 58 | } 59 | } 60 | 61 | public static class NodeHeap { 62 | private Node[] nodes; 63 | private HashMap heapIndexMap; 64 | private HashMap distanceMap; 65 | private int size; 66 | 67 | public NodeHeap(int size) { 68 | nodes = new Node[size]; 69 | heapIndexMap = new HashMap<>(); 70 | distanceMap = new HashMap<>(); 71 | this.size = 0; 72 | } 73 | 74 | public boolean isEmpty() { 75 | return size == 0; 76 | } 77 | 78 | public void addOrUpdateOrIgnore(Node node, int distance) { 79 | if (inHeap(node)) { 80 | distanceMap.put(node, Math.min(distanceMap.get(node), distance)); 81 | insertHeapify(node, heapIndexMap.get(node)); 82 | } 83 | if (!isEntered(node)) { 84 | nodes[size] = node; 85 | heapIndexMap.put(node, size); 86 | distanceMap.put(node, distance); 87 | insertHeapify(node, size++); 88 | } 89 | } 90 | 91 | public NodeRecord pop() { 92 | NodeRecord nodeRecord = new NodeRecord(nodes[0], distanceMap.get(nodes[0])); 93 | swap(0, size - 1); 94 | heapIndexMap.put(nodes[size - 1], -1); 95 | distanceMap.remove(nodes[size - 1]); 96 | nodes[size - 1] = null; 97 | heapify(0, --size); 98 | return nodeRecord; 99 | } 100 | 101 | private void insertHeapify(Node node, int index) { 102 | while (distanceMap.get(nodes[index]) < distanceMap.get(nodes[(index - 1) / 2])) { 103 | swap(index, (index - 1) / 2); 104 | index = (index - 1) / 2; 105 | } 106 | } 107 | 108 | private void heapify(int index, int size) { 109 | int left = index * 2 + 1; 110 | while (left < size) { 111 | int smallest = left + 1 < size && distanceMap.get(nodes[left + 1]) < distanceMap.get(nodes[left]) 112 | ? left + 1 : left; 113 | smallest = distanceMap.get(nodes[smallest]) < distanceMap.get(nodes[index]) ? smallest : index; 114 | if (smallest == index) { 115 | break; 116 | } 117 | swap(smallest, index); 118 | index = smallest; 119 | left = index * 2 + 1; 120 | } 121 | } 122 | 123 | private boolean isEntered(Node node) { 124 | return heapIndexMap.containsKey(node); 125 | } 126 | 127 | private boolean inHeap(Node node) { 128 | return isEntered(node) && heapIndexMap.get(node) != -1; 129 | } 130 | 131 | private void swap(int index1, int index2) { 132 | heapIndexMap.put(nodes[index1], index2); 133 | heapIndexMap.put(nodes[index2], index1); 134 | Node tmp = nodes[index1]; 135 | nodes[index1] = nodes[index2]; 136 | nodes[index2] = tmp; 137 | } 138 | } 139 | 140 | public static HashMap dijkstra2(Node head, int size) { 141 | NodeHeap nodeHeap = new NodeHeap(size); 142 | nodeHeap.addOrUpdateOrIgnore(head, 0); 143 | HashMap result = new HashMap<>(); 144 | while (!nodeHeap.isEmpty()) { 145 | NodeRecord record = nodeHeap.pop(); 146 | Node cur = record.node; 147 | int distance = record.distance; 148 | for (Edge edge : cur.edges) { 149 | nodeHeap.addOrUpdateOrIgnore(edge.to, edge.weight + distance); 150 | } 151 | result.put(cur, distance); 152 | } 153 | return result; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_14_FindFirstIntersectNode.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | /** 4 | * 5 | * 两个单链表相交的一系列问题 6 | 【题目】 在本题中,单链表可能有环,也可能无环。给定两个 7 | 单链表的头节点 head1和head2,这两个链表可能相交,也可能 8 | 不相交。请实现一个函数, 如果两个链表相交,请返回相交的 9 | 第一个节点;如果不相交,返回null 即可。 要求:如果链表1 10 | 的长度为N,链表2的长度为M,时间复杂度请达到 O(N+M),额外 11 | 空间复杂度请达到O(1)。 12 | * 13 | */ 14 | public class Code_14_FindFirstIntersectNode { 15 | 16 | public static class Node { 17 | public int value; 18 | public Node next; 19 | 20 | public Node(int data) { 21 | this.value = data; 22 | } 23 | } 24 | 25 | public static Node getIntersectNode(Node head1, Node head2) { 26 | if (head1 == null || head2 == null) { 27 | return null; 28 | } 29 | Node loop1 = getLoopNode(head1); 30 | Node loop2 = getLoopNode(head2); 31 | if (loop1 == null && loop2 == null) { 32 | return noLoop(head1, head2); 33 | } 34 | if (loop1 != null && loop2 != null) { 35 | return bothLoop(head1, loop1, head2, loop2); 36 | } 37 | return null; 38 | } 39 | /** 40 | * 41 | * 获取环的入口节点 42 | */ 43 | public static Node getLoopNode(Node head) { 44 | if (head == null || head.next == null || head.next.next == null) { 45 | return null; 46 | } 47 | Node n1 = head.next; // n1 -> slow 48 | Node n2 = head.next.next; // n2 -> fast 49 | while (n1 != n2) { 50 | if (n2.next == null || n2.next.next == null) { 51 | return null; 52 | } 53 | n2 = n2.next.next; 54 | n1 = n1.next; 55 | } 56 | n2 = head; // n2 -> walk again from head 57 | while (n1 != n2) { 58 | n1 = n1.next; 59 | n2 = n2.next; 60 | } 61 | return n1; 62 | } 63 | /** 64 | * 两个无环链表 65 | * 66 | */ 67 | public static Node noLoop(Node head1, Node head2) { 68 | if (head1 == null || head2 == null) { 69 | return null; 70 | } 71 | Node cur1 = head1; 72 | Node cur2 = head2; 73 | int n = 0; 74 | while (cur1.next != null) { 75 | n++; 76 | cur1 = cur1.next; 77 | } 78 | while (cur2.next != null) { 79 | n--; 80 | cur2 = cur2.next; 81 | } 82 | if (cur1 != cur2) { 83 | return null; 84 | } 85 | cur1 = n > 0 ? head1 : head2; 86 | cur2 = cur1 == head1 ? head2 : head1; 87 | n = Math.abs(n); 88 | while (n != 0) { 89 | n--; 90 | cur1 = cur1.next; 91 | } 92 | while (cur1 != cur2) { 93 | cur1 = cur1.next; 94 | cur2 = cur2.next; 95 | } 96 | return cur1; 97 | } 98 | /** 99 | * 两个有环链表 100 | * @param head1 第一个链表的头节点 101 | * @param loop1 第一个链表的入环节点 102 | * @param head2 第二个链表的头节点 103 | * @param loop2 第二个链表的入环节点 104 | * @return Node 两个链表第一次相交的节点 105 | */ 106 | public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) { 107 | Node cur1 = null; 108 | Node cur2 = null; 109 | if (loop1 == loop2) { 110 | cur1 = head1; 111 | cur2 = head2; 112 | int n = 0; 113 | while (cur1 != loop1) { 114 | n++; 115 | cur1 = cur1.next; 116 | } 117 | while (cur2 != loop2) { 118 | n--; 119 | cur2 = cur2.next; 120 | } 121 | cur1 = n > 0 ? head1 : head2; 122 | cur2 = cur1 == head1 ? head2 : head1; 123 | n = Math.abs(n); 124 | while (n != 0) { 125 | n--; 126 | cur1 = cur1.next; 127 | } 128 | while (cur1 != cur2) { 129 | cur1 = cur1.next; 130 | cur2 = cur2.next; 131 | } 132 | return cur1; 133 | } else { 134 | cur1 = loop1.next; 135 | while (cur1 != loop1) { 136 | if (cur1 == loop2) { 137 | return loop1; 138 | } 139 | cur1 = cur1.next; 140 | } 141 | return null; 142 | } 143 | } 144 | 145 | public static void main(String[] args) { 146 | // 1->2->3->4->5->6->7->null 147 | Node head1 = new Node(1); 148 | head1.next = new Node(2); 149 | head1.next.next = new Node(3); 150 | head1.next.next.next = new Node(4); 151 | head1.next.next.next.next = new Node(5); 152 | head1.next.next.next.next.next = new Node(6); 153 | head1.next.next.next.next.next.next = new Node(7); 154 | 155 | // 0->9->8->6->7->null 156 | Node head2 = new Node(0); 157 | head2.next = new Node(9); 158 | head2.next.next = new Node(8); 159 | head2.next.next.next = head1.next.next.next.next.next; // 8->6 160 | System.out.println(getIntersectNode(head1, head2).value); 161 | 162 | // 1->2->3->4->5->6->7->4... 163 | head1 = new Node(1); 164 | head1.next = new Node(2); 165 | head1.next.next = new Node(3); 166 | head1.next.next.next = new Node(4); 167 | head1.next.next.next.next = new Node(5); 168 | head1.next.next.next.next.next = new Node(6); 169 | head1.next.next.next.next.next.next = new Node(7); 170 | head1.next.next.next.next.next.next = head1.next.next.next; // 7->4 171 | 172 | // 0->9->8->2... 173 | head2 = new Node(0); 174 | head2.next = new Node(9); 175 | head2.next.next = new Node(8); 176 | head2.next.next.next = head1.next; // 8->2 177 | System.out.println(getIntersectNode(head1, head2).value); 178 | 179 | // 0->9->8->6->4->5->6.. 180 | head2 = new Node(0); 181 | head2.next = new Node(9); 182 | head2.next.next = new Node(8); 183 | head2.next.next.next = head1.next.next.next.next.next; // 8->6 184 | System.out.println(getIntersectNode(head1, head2).value); 185 | 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_02/Code_06_BFPRT.java: -------------------------------------------------------------------------------- 1 | package basic_class_02; 2 | 3 | /** 4 | * 5 | * 在一大堆数中求其前k大或前k小的问题,简称TOP-K问题。 6 | * 而目前解决TOP-K问题最有效的算法即是BFPRT算法 7 | * 8 | */ 9 | public class Code_06_BFPRT { 10 | 11 | // O(N*logK) 12 | public static int[] getMinKNumsByHeap(int[] arr, int k) { 13 | if (k < 1 || k > arr.length) { 14 | return arr; 15 | } 16 | int[] kHeap = new int[k]; 17 | for (int i = 0; i != k; i++) { 18 | heapInsert(kHeap, arr[i], i); 19 | } 20 | for (int i = k; i != arr.length; i++) { 21 | if (arr[i] < kHeap[0]) { 22 | kHeap[0] = arr[i]; 23 | heapify(kHeap, 0, k); 24 | } 25 | } 26 | return kHeap; 27 | } 28 | 29 | public static void heapInsert(int[] arr, int value, int index) { 30 | arr[index] = value; 31 | while (index != 0) { 32 | int parent = (index - 1) / 2; 33 | if (arr[parent] < arr[index]) { 34 | swap(arr, parent, index); 35 | index = parent; 36 | } else { 37 | break; 38 | } 39 | } 40 | } 41 | 42 | public static void heapify(int[] arr, int index, int heapSize) { 43 | int left = index * 2 + 1; 44 | int right = index * 2 + 2; 45 | int largest = index; 46 | while (left < heapSize) { 47 | if (arr[left] > arr[index]) { 48 | largest = left; 49 | } 50 | if (right < heapSize && arr[right] > arr[largest]) { 51 | largest = right; 52 | } 53 | if (largest != index) { 54 | swap(arr, largest, index); 55 | } else { 56 | break; 57 | } 58 | index = largest; 59 | left = index * 2 + 1; 60 | right = index * 2 + 2; 61 | } 62 | } 63 | 64 | // O(N) 65 | public static int[] getMinKNumsByBFPRT(int[] arr, int k) { 66 | if (k < 1 || k > arr.length) { 67 | return arr; 68 | } 69 | int minKth = getMinKthByBFPRT(arr, k); 70 | int[] res = new int[k]; 71 | int index = 0; 72 | for (int i = 0; i != arr.length; i++) { 73 | if (arr[i] < minKth) { 74 | res[index++] = arr[i]; 75 | } 76 | } 77 | for (; index != res.length; index++) { 78 | res[index] = minKth; 79 | } 80 | return res; 81 | } 82 | 83 | public static int getMinKthByBFPRT(int[] arr, int K) { 84 | int[] copyArr = copyArray(arr); 85 | return select(copyArr, 0, copyArr.length - 1, K - 1); 86 | } 87 | 88 | public static int[] copyArray(int[] arr) { 89 | int[] res = new int[arr.length]; 90 | for (int i = 0; i != res.length; i++) { 91 | res[i] = arr[i]; 92 | } 93 | return res; 94 | } 95 | 96 | public static int select(int[] arr, int begin, int end, int i) { 97 | if (begin == end) { 98 | return arr[begin]; 99 | } 100 | int pivot = medianOfMedians(arr, begin, end); 101 | int[] pivotRange = partition(arr, begin, end, pivot); 102 | if (i >= pivotRange[0] && i <= pivotRange[1]) { 103 | return arr[i]; 104 | } else if (i < pivotRange[0]) { 105 | return select(arr, begin, pivotRange[0] - 1, i); 106 | } else { 107 | return select(arr, pivotRange[1] + 1, end, i); 108 | } 109 | } 110 | 111 | public static int medianOfMedians(int[] arr, int begin, int end) { 112 | int num = end - begin + 1; 113 | int offset = num % 5 == 0 ? 0 : 1; 114 | int[] mArr = new int[num / 5 + offset]; 115 | for (int i = 0; i < mArr.length; i++) { 116 | int beginI = begin + i * 5; 117 | int endI = beginI + 4; 118 | mArr[i] = getMedian(arr, beginI, Math.min(end, endI)); 119 | } 120 | return select(mArr, 0, mArr.length - 1, mArr.length / 2); 121 | } 122 | 123 | public static int[] partition(int[] arr, int begin, int end, int pivotValue) { 124 | int small = begin - 1; 125 | int cur = begin; 126 | int big = end + 1; 127 | while (cur != big) { 128 | if (arr[cur] < pivotValue) { 129 | swap(arr, ++small, cur++); 130 | } else if (arr[cur] > pivotValue) { 131 | swap(arr, cur, --big); 132 | } else { 133 | cur++; 134 | } 135 | } 136 | int[] range = new int[2]; 137 | range[0] = small + 1; 138 | range[1] = big - 1; 139 | return range; 140 | } 141 | 142 | public static int getMedian(int[] arr, int begin, int end) { 143 | insertionSort(arr, begin, end); 144 | int sum = end + begin; 145 | int mid = (sum / 2) + (sum % 2); 146 | return arr[mid]; 147 | } 148 | 149 | public static void insertionSort(int[] arr, int begin, int end) { 150 | for (int i = begin + 1; i != end + 1; i++) { 151 | for (int j = i; j != begin; j--) { 152 | if (arr[j - 1] > arr[j]) { 153 | swap(arr, j - 1, j); 154 | } else { 155 | break; 156 | } 157 | } 158 | } 159 | } 160 | 161 | public static void swap(int[] arr, int index1, int index2) { 162 | int tmp = arr[index1]; 163 | arr[index1] = arr[index2]; 164 | arr[index2] = tmp; 165 | } 166 | 167 | public static void printArray(int[] arr) { 168 | for (int i = 0; i != arr.length; i++) { 169 | System.out.print(arr[i] + " "); 170 | } 171 | System.out.println(); 172 | } 173 | 174 | public static void main(String[] args) { 175 | int[] arr = { 6, 9, 1, 3, 1, 2, 2, 5, 6, 1, 3, 5, 9, 7, 2, 5, 6, 1, 9 }; 176 | // sorted : { 1, 1, 1, 1, 2, 2, 2, 3, 3, 5, 5, 5, 6, 6, 6, 7, 9, 9, 9 } 177 | printArray(getMinKNumsByHeap(arr, 10)); 178 | printArray(getMinKNumsByBFPRT(arr, 10)); 179 | 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_04/Code_04_SerializeAndReconstructTree.java: -------------------------------------------------------------------------------- 1 | package class_04; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | /** 6 | * 7 | * 二叉树的序列化和反序列化 8 | * 9 | */ 10 | public class Code_04_SerializeAndReconstructTree { 11 | 12 | public static class Node { 13 | public int value; 14 | public Node left; 15 | public Node right; 16 | 17 | public Node(int data) { 18 | this.value = data; 19 | } 20 | } 21 | //二叉树的序列化 22 | public static String serialByPre(Node head) { 23 | if (head == null) { 24 | return "#!"; 25 | } 26 | String res = head.value + "!"; 27 | res += serialByPre(head.left); 28 | res += serialByPre(head.right); 29 | return res; 30 | } 31 | 32 | public static Node reconByPreString(String preStr) { 33 | String[] values = preStr.split("!"); 34 | Queue queue = new LinkedList(); 35 | for (int i = 0; i != values.length; i++) { 36 | queue.offer(values[i]); 37 | } 38 | return reconPreOrder(queue); 39 | } 40 | 41 | public static Node reconPreOrder(Queue queue) { 42 | String value = queue.poll(); 43 | if (value.equals("#")) { 44 | return null; 45 | } 46 | Node head = new Node(Integer.valueOf(value)); 47 | head.left = reconPreOrder(queue); 48 | head.right = reconPreOrder(queue); 49 | return head; 50 | } 51 | //按层序列化 52 | public static String serialByLevel(Node head) { 53 | if (head == null) { 54 | return "#!"; 55 | } 56 | String res = head.value + "!"; 57 | Queue queue = new LinkedList(); 58 | queue.offer(head); 59 | while (!queue.isEmpty()) { 60 | head = queue.poll(); 61 | if (head.left != null) { 62 | res += head.left.value + "!"; 63 | queue.offer(head.left); 64 | } else { 65 | res += "#!"; 66 | } 67 | if (head.right != null) { 68 | res += head.right.value + "!"; 69 | queue.offer(head.right); 70 | } else { 71 | res += "#!"; 72 | } 73 | } 74 | return res; 75 | } 76 | 77 | public static Node reconByLevelString(String levelStr) { 78 | String[] values = levelStr.split("!"); 79 | int index = 0; 80 | Node head = generateNodeByString(values[index++]); 81 | Queue queue = new LinkedList(); 82 | if (head != null) { 83 | queue.offer(head); 84 | } 85 | Node node = null; 86 | while (!queue.isEmpty()) { 87 | node = queue.poll(); 88 | node.left = generateNodeByString(values[index++]); 89 | node.right = generateNodeByString(values[index++]); 90 | if (node.left != null) { 91 | queue.offer(node.left); 92 | } 93 | if (node.right != null) { 94 | queue.offer(node.right); 95 | } 96 | } 97 | return head; 98 | } 99 | 100 | public static Node generateNodeByString(String val) { 101 | if (val.equals("#")) { 102 | return null; 103 | } 104 | return new Node(Integer.valueOf(val)); 105 | } 106 | 107 | // for test -- print tree 108 | public static void printTree(Node head) { 109 | System.out.println("Binary Tree:"); 110 | printInOrder(head, 0, "H", 17); 111 | System.out.println(); 112 | } 113 | 114 | public static void printInOrder(Node head, int height, String to, int len) { 115 | if (head == null) { 116 | return; 117 | } 118 | printInOrder(head.right, height + 1, "v", len); 119 | String val = to + head.value + to; 120 | int lenM = val.length(); 121 | int lenL = (len - lenM) / 2; 122 | int lenR = len - lenM - lenL; 123 | val = getSpace(lenL) + val + getSpace(lenR); 124 | System.out.println(getSpace(height * len) + val); 125 | printInOrder(head.left, height + 1, "^", len); 126 | } 127 | 128 | public static String getSpace(int num) { 129 | String space = " "; 130 | StringBuffer buf = new StringBuffer(""); 131 | for (int i = 0; i < num; i++) { 132 | buf.append(space); 133 | } 134 | return buf.toString(); 135 | } 136 | 137 | public static void main(String[] args) { 138 | Node head = null; 139 | printTree(head); 140 | 141 | String pre = serialByPre(head); 142 | System.out.println("serialize tree by pre-order: " + pre); 143 | head = reconByPreString(pre); 144 | System.out.print("reconstruct tree by pre-order, "); 145 | printTree(head); 146 | 147 | String level = serialByLevel(head); 148 | System.out.println("serialize tree by level: " + level); 149 | head = reconByLevelString(level); 150 | System.out.print("reconstruct tree by level, "); 151 | printTree(head); 152 | 153 | System.out.println("===================================="); 154 | 155 | head = new Node(1); 156 | printTree(head); 157 | 158 | pre = serialByPre(head); 159 | System.out.println("serialize tree by pre-order: " + pre); 160 | head = reconByPreString(pre); 161 | System.out.print("reconstruct tree by pre-order, "); 162 | printTree(head); 163 | 164 | level = serialByLevel(head); 165 | System.out.println("serialize tree by level: " + level); 166 | head = reconByLevelString(level); 167 | System.out.print("reconstruct tree by level, "); 168 | printTree(head); 169 | 170 | System.out.println("===================================="); 171 | 172 | head = new Node(1); 173 | head.left = new Node(2); 174 | head.right = new Node(3); 175 | head.left.left = new Node(4); 176 | head.right.right = new Node(5); 177 | printTree(head); 178 | 179 | pre = serialByPre(head); 180 | System.out.println("serialize tree by pre-order: " + pre); 181 | head = reconByPreString(pre); 182 | System.out.print("reconstruct tree by pre-order, "); 183 | printTree(head); 184 | 185 | level = serialByLevel(head); 186 | System.out.println("serialize tree by level: " + level); 187 | head = reconByLevelString(level); 188 | System.out.print("reconstruct tree by level, "); 189 | printTree(head); 190 | 191 | System.out.println("===================================="); 192 | 193 | head = new Node(100); 194 | head.left = new Node(21); 195 | head.left.left = new Node(37); 196 | head.right = new Node(-42); 197 | head.right.left = new Node(0); 198 | head.right.right = new Node(666); 199 | printTree(head); 200 | 201 | pre = serialByPre(head); 202 | System.out.println("serialize tree by pre-order: " + pre); 203 | head = reconByPreString(pre); 204 | System.out.print("reconstruct tree by pre-order, "); 205 | printTree(head); 206 | 207 | level = serialByLevel(head); 208 | System.out.println("serialize tree by level: " + level); 209 | head = reconByLevelString(level); 210 | System.out.print("reconstruct tree by level, "); 211 | printTree(head); 212 | 213 | System.out.println("===================================="); 214 | 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/class_03/Code_11_IsPalindromeList.java: -------------------------------------------------------------------------------- 1 | package class_03; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * 7 | * 判断一个链表是否为回文结构 8 | 【题目】 给定一个链表的头节点head,请判断该链表是否为回 9 | 文结构。 例如: 1->2->1,返回true。 1->2->2->1,返回true。 10 | 15->6->15,返回true。 1->2->3,返回false。 11 | 进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂 12 | 度达到O(1)。 13 | * 14 | */ 15 | public class Code_11_IsPalindromeList { 16 | 17 | public static class Node { 18 | public int value; 19 | public Node next; 20 | 21 | public Node(int data) { 22 | this.value = data; 23 | } 24 | } 25 | 26 | // need n extra space 27 | public static boolean isPalindrome1(Node head) { 28 | Stack stack = new Stack(); 29 | Node cur = head; 30 | while (cur != null) { 31 | stack.push(cur); 32 | cur = cur.next; 33 | } 34 | while (head != null) { 35 | if (head.value != stack.pop().value) { 36 | return false; 37 | } 38 | head = head.next; 39 | } 40 | return true; 41 | } 42 | 43 | // need n/2 extra space 44 | public static boolean isPalindrome2(Node head) { 45 | if (head == null || head.next == null) { 46 | return true; 47 | } 48 | Node right = head.next; 49 | Node cur = head; 50 | while (cur.next != null && cur.next.next != null) { 51 | right = right.next; 52 | cur = cur.next.next; 53 | } 54 | Stack stack = new Stack(); 55 | while (right != null) { 56 | stack.push(right); 57 | right = right.next; 58 | } 59 | while (!stack.isEmpty()) { 60 | if (head.value != stack.pop().value) { 61 | return false; 62 | } 63 | head = head.next; 64 | } 65 | return true; 66 | } 67 | 68 | // need O(1) extra space 69 | public static boolean isPalindrome3(Node head) { 70 | if (head == null || head.next == null) { 71 | return true; 72 | } 73 | Node n1 = head; 74 | Node n2 = head; 75 | while (n2.next != null && n2.next.next != null) { // find mid node 76 | n1 = n1.next; // n1 -> mid 77 | n2 = n2.next.next; // n2 -> end 78 | } 79 | n2 = n1.next; // n2 -> right part first node 80 | n1.next = null; // mid.next -> null 81 | Node n3 = null; 82 | while (n2 != null) { // right part convert 83 | n3 = n2.next; // n3 -> save next node 84 | n2.next = n1; // next of right node convert 85 | n1 = n2; // n1 move 86 | n2 = n3; // n2 move 87 | } 88 | n3 = n1; // n3 -> save last node 89 | n2 = head;// n2 -> left first node 90 | boolean res = true; 91 | while (n1 != null && n2 != null) { // check palindrome 92 | if (n1.value != n2.value) { 93 | res = false; 94 | break; 95 | } 96 | n1 = n1.next; // left to mid 97 | n2 = n2.next; // right to mid 98 | } 99 | n1 = n3.next; 100 | n3.next = null; 101 | while (n1 != null) { // recover list 102 | n2 = n1.next; 103 | n1.next = n3; 104 | n3 = n1; 105 | n1 = n2; 106 | } 107 | return res; 108 | } 109 | 110 | public static void printLinkedList(Node node) { 111 | System.out.print("Linked List: "); 112 | while (node != null) { 113 | System.out.print(node.value + " "); 114 | node = node.next; 115 | } 116 | System.out.println(); 117 | } 118 | 119 | public static void main(String[] args) { 120 | 121 | Node head = null; 122 | printLinkedList(head); 123 | System.out.print(isPalindrome1(head) + " | "); 124 | System.out.print(isPalindrome2(head) + " | "); 125 | System.out.println(isPalindrome3(head) + " | "); 126 | printLinkedList(head); 127 | System.out.println("========================="); 128 | 129 | head = new Node(1); 130 | printLinkedList(head); 131 | System.out.print(isPalindrome1(head) + " | "); 132 | System.out.print(isPalindrome2(head) + " | "); 133 | System.out.println(isPalindrome3(head) + " | "); 134 | printLinkedList(head); 135 | System.out.println("========================="); 136 | 137 | head = new Node(1); 138 | head.next = new Node(2); 139 | printLinkedList(head); 140 | System.out.print(isPalindrome1(head) + " | "); 141 | System.out.print(isPalindrome2(head) + " | "); 142 | System.out.println(isPalindrome3(head) + " | "); 143 | printLinkedList(head); 144 | System.out.println("========================="); 145 | 146 | head = new Node(1); 147 | head.next = new Node(1); 148 | printLinkedList(head); 149 | System.out.print(isPalindrome1(head) + " | "); 150 | System.out.print(isPalindrome2(head) + " | "); 151 | System.out.println(isPalindrome3(head) + " | "); 152 | printLinkedList(head); 153 | System.out.println("========================="); 154 | 155 | head = new Node(1); 156 | head.next = new Node(2); 157 | head.next.next = new Node(3); 158 | printLinkedList(head); 159 | System.out.print(isPalindrome1(head) + " | "); 160 | System.out.print(isPalindrome2(head) + " | "); 161 | System.out.println(isPalindrome3(head) + " | "); 162 | printLinkedList(head); 163 | System.out.println("========================="); 164 | 165 | head = new Node(1); 166 | head.next = new Node(2); 167 | head.next.next = new Node(1); 168 | printLinkedList(head); 169 | System.out.print(isPalindrome1(head) + " | "); 170 | System.out.print(isPalindrome2(head) + " | "); 171 | System.out.println(isPalindrome3(head) + " | "); 172 | printLinkedList(head); 173 | System.out.println("========================="); 174 | 175 | head = new Node(1); 176 | head.next = new Node(2); 177 | head.next.next = new Node(3); 178 | head.next.next.next = new Node(1); 179 | printLinkedList(head); 180 | System.out.print(isPalindrome1(head) + " | "); 181 | System.out.print(isPalindrome2(head) + " | "); 182 | System.out.println(isPalindrome3(head) + " | "); 183 | printLinkedList(head); 184 | System.out.println("========================="); 185 | 186 | head = new Node(1); 187 | head.next = new Node(2); 188 | head.next.next = new Node(2); 189 | head.next.next.next = new Node(1); 190 | printLinkedList(head); 191 | System.out.print(isPalindrome1(head) + " | "); 192 | System.out.print(isPalindrome2(head) + " | "); 193 | System.out.println(isPalindrome3(head) + " | "); 194 | printLinkedList(head); 195 | System.out.println("========================="); 196 | 197 | head = new Node(1); 198 | head.next = new Node(2); 199 | head.next.next = new Node(3); 200 | head.next.next.next = new Node(2); 201 | head.next.next.next.next = new Node(1); 202 | printLinkedList(head); 203 | System.out.print(isPalindrome1(head) + " | "); 204 | System.out.print(isPalindrome2(head) + " | "); 205 | System.out.println(isPalindrome3(head) + " | "); 206 | printLinkedList(head); 207 | System.out.println("========================="); 208 | 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /basic_class_nowcoder/src/basic_class_01/Code_05_MergeSort.java: -------------------------------------------------------------------------------- 1 | package basic_class_01; 2 | 3 | import java.util.Arrays; 4 | /** 5 | * master公式的使用 6 | * T(N) = a*T(N/b) + O(N^d)1) 7 | * log(b,a) > d -> 复杂度为O(N^log(b,a))2) 8 | * log(b,a) = d -> 复杂度为O(N^d * logN)3) 9 | * log(b,a) < d -> 复杂度为O(N^d) 10 | * 归并排序的细节讲解与复杂度分析 11 | * 时间复杂度O(N*logN),额外空间复杂度O(N) 12 | * 13 | */ 14 | public class Code_05_MergeSort { 15 | 16 | public static void mergeSort(int[] arr) { 17 | if (arr == null || arr.length < 2) { 18 | return; 19 | } 20 | mergeSort(arr, 0, arr.length - 1); 21 | } 22 | 23 | public static void mergeSort(int[] arr, int l, int r) { 24 | if (l == r) { 25 | return; 26 | } 27 | int mid = l + ((r - l) >> 1); 28 | mergeSort(arr, l, mid); 29 | mergeSort(arr, mid + 1, r); 30 | merge(arr, l, mid, r); 31 | } 32 | 33 | public static void merge(int[] arr, int l, int m, int r) { 34 | int[] help = new int[r - l + 1]; 35 | int i = 0; 36 | int p1 = l; 37 | int p2 = m + 1; 38 | while (p1 <= m && p2 <= r) { 39 | help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++]; 40 | } 41 | while (p1 <= m) { 42 | help[i++] = arr[p1++]; 43 | } 44 | while (p2 <= r) { 45 | help[i++] = arr[p2++]; 46 | } 47 | for (i = 0; i < help.length; i++) { 48 | arr[l + i] = help[i]; 49 | } 50 | } 51 | 52 | // for test 53 | public static void comparator(int[] arr) { 54 | Arrays.sort(arr); 55 | } 56 | 57 | // for test 58 | public static int[] generateRandomArray(int maxSize, int maxValue) { 59 | int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 60 | for (int i = 0; i < arr.length; i++) { 61 | arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 62 | } 63 | return arr; 64 | } 65 | 66 | // for test 67 | public static int[] copyArray(int[] arr) { 68 | if (arr == null) { 69 | return null; 70 | } 71 | int[] res = new int[arr.length]; 72 | for (int i = 0; i < arr.length; i++) { 73 | res[i] = arr[i]; 74 | } 75 | return res; 76 | } 77 | 78 | // for test 79 | public static boolean isEqual(int[] arr1, int[] arr2) { 80 | if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 81 | return false; 82 | } 83 | if (arr1 == null && arr2 == null) { 84 | return true; 85 | } 86 | if (arr1.length != arr2.length) { 87 | return false; 88 | } 89 | for (int i = 0; i < arr1.length; i++) { 90 | if (arr1[i] != arr2[i]) { 91 | return false; 92 | } 93 | } 94 | return true; 95 | } 96 | 97 | // for test 98 | public static void printArray(int[] arr) { 99 | if (arr == null) { 100 | return; 101 | } 102 | for (int i = 0; i < arr.length; i++) { 103 | System.out.print(arr[i] + " "); 104 | } 105 | System.out.println(); 106 | } 107 | 108 | // for test 109 | public static void main(String[] args) { 110 | int testTime = 500000; 111 | int maxSize = 100; 112 | int maxValue = 100; 113 | boolean succeed = true; 114 | for (int i = 0; i < testTime; i++) { 115 | int[] arr1 = generateRandomArray(maxSize, maxValue); 116 | int[] arr2 = copyArray(arr1); 117 | mergeSort(arr1); 118 | comparator(arr2); 119 | if (!isEqual(arr1, arr2)) { 120 | succeed = false; 121 | printArray(arr1); 122 | printArray(arr2); 123 | break; 124 | } 125 | } 126 | System.out.println(succeed ? "Nice!" : "Fucking fucked!"); 127 | 128 | int[] arr = generateRandomArray(maxSize, maxValue); 129 | printArray(arr); 130 | mergeSort(arr); 131 | printArray(arr); 132 | 133 | } 134 | 135 | } 136 | /** 137 | 1,归并排序的额外空间复杂度可以变成O(1),但是非常难, 138 | 不需要掌握可以搜"归并排序 内部缓存" 139 | 140 | 141 | 142 | //遍历二叉树的神级方法 时间复杂度为O(N),空间复杂度为O(1) 143 | 144 | 145 | public class MorrisTraversal { 146 | 147 | //二叉树节点的定义 148 | public static class Node { 149 | public int value; 150 | Node left; 151 | Node right; 152 | 153 | public Node(int data) { 154 | this.value = data; 155 | } 156 | } 157 | //Morris中序遍历 158 | public static void morrisIn(Node head) { 159 | if (head == null) { 160 | return; 161 | } 162 | Node cur1 = head; 163 | Node cur2 = null; 164 | while (cur1 != null) { 165 | cur2 = cur1.left; 166 | if (cur2 != null) { 167 | while (cur2.right != null && cur2.right != cur1) { 168 | cur2 = cur2.right; 169 | } 170 | if (cur2.right == null) { 171 | cur2.right = cur1; 172 | cur1 = cur1.left; 173 | continue; 174 | } else { 175 | cur2.right = null; 176 | } 177 | } 178 | System.out.print(cur1.value + " "); 179 | cur1 = cur1.right; 180 | } 181 | System.out.println(); 182 | } 183 | //Morris先序遍历 184 | public static void morrisPre(Node head) { 185 | if (head == null) { 186 | return; 187 | } 188 | Node cur1 = head; 189 | Node cur2 = null; 190 | while (cur1 != null) { 191 | cur2 = cur1.left; 192 | if (cur2 != null) { 193 | while (cur2.right != null && cur2.right != cur1) { 194 | cur2 = cur2.right; 195 | } 196 | if (cur2.right == null) { 197 | cur2.right = cur1; 198 | System.out.print(cur1.value + " "); 199 | cur1 = cur1.left; 200 | continue; 201 | } else { 202 | cur2.right = null; 203 | } 204 | } else { 205 | System.out.print(cur1.value + " "); 206 | } 207 | cur1 = cur1.right; 208 | } 209 | System.out.println(); 210 | } 211 | //Morris后序遍历 212 | public static void morrisPos(Node head) { 213 | if (head == null) { 214 | return; 215 | } 216 | Node cur1 = head; 217 | Node cur2 = null; 218 | while (cur1 != null) { 219 | cur2 = cur1.left; 220 | if (cur2 != null) { 221 | while (cur2.right != null && cur2.right != cur1) { 222 | cur2 = cur2.right; 223 | } 224 | if (cur2.right == null) { 225 | cur2.right = cur1; 226 | cur1 = cur1.left; 227 | continue; 228 | } else { 229 | cur2.right = null; 230 | printEdge(cur1.left); 231 | } 232 | } 233 | cur1 = cur1.right; 234 | } 235 | printEdge(head); 236 | System.out.println(); 237 | } 238 | 239 | public static void printEdge(Node head) { 240 | Node tail = reverseEdge(head); 241 | Node cur = tail; 242 | while (cur != null) { 243 | System.out.print(cur.value + " "); 244 | cur = cur.right; 245 | } 246 | reverseEdge(tail); 247 | } 248 | 249 | public static Node reverseEdge(Node from) { 250 | Node pre = null; 251 | Node next = null; 252 | while (from != null) { 253 | next = from.right; 254 | from.right = pre; 255 | pre = from; 256 | from = next; 257 | } 258 | return pre; 259 | } 260 | 261 | // for test -- print tree(直观地打印二叉树) 262 | public static void printTree(Node head) { 263 | System.out.println("Binary Tree:"); 264 | printInOrder(head, 0, "H", 17); 265 | System.out.println(); 266 | } 267 | 268 | public static void printInOrder(Node head, int height, String to, int len) { 269 | if (head == null) { 270 | return; 271 | } 272 | printInOrder(head.right, height + 1, "v", len); 273 | String val = to + head.value + to; 274 | int lenM = val.length(); 275 | int lenL = (len - lenM) / 2; 276 | int lenR = len - lenM - lenL; 277 | val = getSpace(lenL) + val + getSpace(lenR); 278 | System.out.println(getSpace(height * len) + val); 279 | printInOrder(head.left, height + 1, "^", len); 280 | } 281 | 282 | public static String getSpace(int num) { 283 | String space = " "; 284 | StringBuffer buf = new StringBuffer(""); 285 | for (int i = 0; i < num; i++) { 286 | buf.append(space); 287 | } 288 | return buf.toString(); 289 | } 290 | 291 | public static void main(String[] args) { 292 | Node head = new Node(4); 293 | head.left = new Node(2); 294 | head.right = new Node(6); 295 | head.left.left = new Node(1); 296 | head.left.right = new Node(3); 297 | head.right.left = new Node(5); 298 | head.right.right = new Node(7); 299 | printTree(head); 300 | morrisIn(head); //中序 301 | morrisPre(head); //先序 302 | morrisPos(head); //后序 303 | printTree(head); 304 | 305 | } 306 | 307 | } 308 | */ 309 | 310 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | > `basic_class_nowcoder`:牛客网算法基础班源码。 8 | ### 视频&&PPT请联系 9 | 10 | > `QQ:1072966956(免费)` 11 | 12 |
13 | 14 | 15 | |⚔️ | 🖥 | 🚏 | 🏖 | 🌁| 📮 | 🔍 | 🚀 | 16 | | :--------: | :---------: | :---------: | :---------: | :---------: | :---------:| :---------: | :-------: | 17 | | [课程01](#basic_class_001) | [课程02](#-basic_class_02)|[课程03](#-basic_class_03) | [课程04](#-basic_class_04) |[课程05](#-basic_class_05)|[课程06](#-basic_class_06)| [课程07](#-basic_class_07) |[课程08](#-basic_class_08)| 18 | 19 | 20 | 21 | ### ⚔️basic_class_001 22 | - [01.冒泡排序 - BubbleSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_00_BubbleSort.java) 23 | 24 | - [02.插入排序 - InsertionSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_01_InsertionSort.java) 25 | 26 | - [03.选择排序 - SelectionSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_02_SelectionSort.java) 27 | 28 | - [04.堆排序 --- HeapSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_03_HeapSort.java) 29 | 30 | - [05.快速排序 - QuickSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_04_QuickSort.java) 31 | 32 | - [06.归并排序 - MergeSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_05_MergeSort.java) 33 | 34 | - [07.桶排序 --- BucketSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_06_BucketSort.java) 35 | 36 | - [08.基数排序 - RadixSort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_07_RadixSort.java) 37 | 38 | - [09.荷兰国旗问题](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_08_NetherlandsFlag.java) 39 | 40 | - [10.自定义排序规则](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_09_Comparator.java) 41 | 42 | - [11.已知A、B两个数组,求在B中且不在A中的元素](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_10_GetAllNotIncluded.java) 43 | 44 | - [12.给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_11_MaxGap.java) 45 | 46 | - [13.在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_01/Code_12_SmallSum.java) 47 | 48 | ### 🖥 basic_class_02 49 | - [01.KMP字符串匹配算法](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_02/Code_01_KMP.java) 50 | 51 | - [02.KMP_ShortestHaveTwice](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_02/Code_02_KMP_ShortestHaveTwice.java) 52 | 53 | - [03.KMP_T1SubtreeEqualsT2给定两个二叉树T1和T2, 返回T1的某个子树结构是否与T2的结构相等](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_02/Code_03_KMP_T1SubtreeEqualsT2.java) 54 | 55 | - [04.Manacher 给定一个字符串,求出其最长回文子串的长度](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_02/Code_04_Manacher.java) 56 | 57 | - [05.Manacher_ShortestEnd 给定一个字符串str1,只能往str1的后面添加字符变成str2,要求str2整体都是回文串且最短](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_02/Code_05_Manacher_ShortestEnd.java) 58 | 59 | - [06.BFPRT在一大堆数中求其前k大或前k小的问题](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/basic_class_02/Code_06_BFPRT.java) 60 | 61 | ### 🚏 basic_class_03 62 | - [01.Array_To_Stack_Queue 用数组结构实现大小固定的队列和栈](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_01_Array_To_Stack_Queue.java) 63 | 64 | - [02.Code_02_GetMinStack 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_02_GetMinStack.java) 65 | 66 | - [03.StackAndQueueConvert 如何仅用队列结构实现栈结构?如何仅用栈结构实现队列结构?](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_03_StackAndQueueConvert.java) 67 | 68 | - [04.DogCatQueue 猫狗队列](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_04_DogCatQueue.java) 69 | 70 | - [05.RotateMatrix 转圈打印矩阵](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_05_RotateMatrix.java) 71 | 72 | - [06.PrintMatrixSpiralOrder 旋转正方形矩阵](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_06_PrintMatrixSpiralOrder.java) 73 | 74 | - [07.ReverseList 反转单向和双向链表](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_07_ReverseList.java) 75 | 76 | - [08.ZigZagPrintMatrix “之”字形打印矩阵](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_08_ZigZagPrintMatrix.java) 77 | 78 | - [09.FindNumInSortedMatrix 在行列都排好序的矩阵中找数](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_09_FindNumInSortedMatrix.java) 79 | 80 | - [10.PrintCommonPart 打印两个有序链表的公共部分](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_10_PrintCommonPart.java) 81 | 82 | - [11.IsPalindromeList 判断一个链表是否为回文结构](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_11_IsPalindromeList.java) 83 | 84 | - [12.SmallerEqualBigger 将单向链表按某值划分成左边小、中间相等、右边大的形式](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_12_SmallerEqualBigger.java) 85 | 86 | - [13.CopyListWithRandom 复制含有随机指针节点的链表](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_13_CopyListWithRandom.java) 87 | 88 | - [14.FindFirstIntersectNode 两个单链表相交的一系列问题](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_14_FindFirstIntersectNode.java) 89 | 90 | - [15.FindOneLessValueIndex 搜索局部最小](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_03/Code_15_FindOneLessValueIndex.java) 91 | 92 | ### 🏖 basic_class_04 93 | 94 | - [01.PreInPosTraversal 二叉树的先序、中序、后序遍历(递归/非递归)](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_01_PreInPosTraversal.java) 95 | 96 | - [02.PrintBinaryTree (福利)打印整个二叉树](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_02_PrintBinaryTree.java) 97 | 98 | - [03.SuccessorNode 在二叉树中找到一个节点的后继节点](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_03_SuccessorNode.java) 99 | 100 | 101 | - [04.SerializeAndReconstructTree 二叉树的序列化和反序列化](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_04_SerializeAndReconstructTree.java) 102 | 103 | - [05.PaperFolding 折纸问题](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_05_PaperFolding.java) 104 | 105 | - [06.IsBalancedTree 判断一棵二叉树是否是平衡二叉树](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_06_IsBalancedTree.java) 106 | 107 | - [07.IsBSTAndCBT 树是否是搜索二叉树/完全二叉树](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_07_IsBSTAndCBT.java) 108 | 109 | - [08.CompleteTreeNodeNumber 求完全二叉树节点的个数](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_04/Code_08_CompleteTreeNodeNumber.java) 110 | 111 | ### 🌁 basic_class_05 112 | 113 | - [01.HashMap 认识哈希函数和哈希表](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_05/Code_01_HashMap.java) 114 | 115 | - [02.RandomPool 设计RandomPool结构](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_05/Code_02_RandomPool.java) 116 | 117 | - [03.Islands 岛问题](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_05/Code_03_Islands.java) 118 | 119 | - [04.UnionFind 并查集结构](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_05/Code_04_UnionFind.java) 120 | 121 | - [05.bulongguolvqi 布隆过滤器](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_05/class_05_bulongguolvqi.java) 122 | 123 | 124 | 125 | ### 📮 basic_class_06 126 | 127 | - [Edge 边](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Edge.java) 128 | - [Graph 图](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Graph.java) 129 | - [GraphGenerator 图的生成](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/GraphGenerator.java) 130 | - [Node 节点](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Node.java) 131 | 132 | - [01.BFS](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Code_01_BFS.java) 133 | 134 | - [02.DFS](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Code_02_DFS.java) 135 | 136 | - [03.TopologySort](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Code_03_TopologySort.java) 137 | 138 | - [04.Kruskal](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Code_04_Kruskal.java) 139 | 140 | - [05.Prim](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Code_05_Prim.java) 141 | 142 | - [06.Dijkstra](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_06/Code_06_Dijkstra.java) 143 | 144 | ### 🔍 basic_class_07 145 | 146 | - [01.TrieTree 前缀树](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_07/Code_01_TrieTree.java) 147 | 148 | - [02.Less_Money 金条切割](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_07/Code_02_Less_Money.java) 149 | 150 | - [03.IPO](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_07/Code_03_IPO.java) 151 | 152 | - [04.MadianQuick 一个数据流中,随时可以取得中位数](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_07/Code_04_MadianQuick.java) 153 | 154 | - [05.LowestLexicography 最低的字典序](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_07/Code_05_LowestLexicography.java) 155 | 156 | - [06.BestArrange 会议室宣讲](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_07/Code_06_BestArrange.java) 157 | 158 | ### 🚀 basic_class_08 159 | 160 | - [01.Factorial 求n!的结果](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_01_Factorial.java) 161 | 162 | - [02.Hanoi 汉诺塔](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_02_Hanoi.java) 163 | 164 | - [03.Print_All_Subsquences 打印一个字符串的全部子序列](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_03_Print_All_Subsquences.java) 165 | 166 | - [04.Print_All_Permutations 打印一个字符串的全部排列](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_04_Print_All_Permutations.java) 167 | 168 | - [05.Cow 母牛生母牛](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_05_Cow.java) 169 | 170 | - [06.ReverseStackUsingRecursive 用递归翻转一个栈](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_06_ReverseStackUsingRecursive.java) 171 | 172 | - [07.MinPath 二维数组最小的路径和](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_07_MinPath.java) 173 | 174 | - [08.Money_Problem 数组arr中的数字累加得到aim](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_08_Money_Problem.java) 175 | - [09.Knapsack 背包问题](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Code_09_Knapsack.java) 176 | 177 | - [FaceBook 一个数字串,能转变成多少种字母串](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/FaceBook.java) 178 | - [Test](https://github.com/JasonZhangCauc/basic_class_nowcoder/blob/master/basic_class_nowcoder/src/class_08/Test.java) 179 | 180 | 181 | 182 | 183 | 184 | --------------------------------------------------------------------------------