();
22 | TreeNode res = null;
23 | int count = 0;
24 | TreeNode p = pRoot;
25 | while (p != null || !stack.isEmpty()){
26 | while (p != null){
27 | stack.push(p);
28 | p = p.left;
29 | }
30 | TreeNode p1 = stack.pop();
31 | count++;
32 | if(count == k){
33 | return p1;
34 | }
35 |
36 | p = p1.right;
37 | }
38 | return res;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Main10.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/18
6 | * Time: 20:28
7 | */
8 |
9 | import java.util.Scanner;
10 |
11 | public class Main10 {
12 | public static void main(String [] args){
13 | Scanner sc=new Scanner(System.in);
14 | String N=sc.nextLine();
15 | int n=Integer.parseInt(N);
16 | int[] arr = new int[n];
17 | for (int i = 0; i < n; i++) {
18 | arr[i] = sc.nextInt();
19 |
20 | }
21 | int sum=0;
22 | long l1 = System.currentTimeMillis();
23 |
24 | for (int i = 0; i < n-1; i++) {
25 |
26 | int small = 0;
27 | int big = 0;
28 | if(arr[i] < arr[i+1]){
29 | small = arr[i];
30 | big = arr[i+1];
31 | }else {
32 | small = arr[i+1];
33 | big = arr[i];
34 | }
35 |
36 | for (int j = i+1; j < n; j++) {
37 | if(small > arr[j]){
38 | small = arr[j];
39 | }
40 | if(arr[j] > big){
41 | big = arr[j];
42 | }
43 | sum += (big-small);
44 |
45 | }
46 |
47 | }
48 |
49 | System.out.println(sum);
50 | long l2 = System.currentTimeMillis();
51 | System.out.println(l2-l1);
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Main4.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/17
8 | * Time: 16:32
9 | *
10 | * 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的
11 | */
12 |
13 | public class Main4 {
14 | boolean isSymmetrical(TreeNode pRoot)
15 | {
16 | if(pRoot == null){
17 | return true;
18 | }
19 | return isSymmetrical(pRoot.left,pRoot.right);
20 |
21 | }
22 | private boolean isSymmetrical(TreeNode left,TreeNode right){
23 | if(left == null && right == null){
24 | return true;
25 | }
26 | if(left == null || right == null){
27 | return false;
28 | }
29 | if(left.val == right.val){
30 | return isSymmetrical(left.left,right.right)&&isSymmetrical(left.right,right.left);
31 | }
32 | return false;
33 | }
34 |
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Main5.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/17
8 | * Time: 21:59
9 | * 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,
10 | * 最长路径的长度为树的深度
11 | */
12 |
13 | public class Main5 {
14 | public int TreeDepth(TreeNode root) {
15 | if(root == null){
16 | return 0;
17 | }
18 | return TreeDepth(root.left)>TreeDepth(root.right)?TreeDepth(root.left)+1:TreeDepth(root.right)+1;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/MinSubArrayLen.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * jianzhioffer 209
5 | * 给定一个由 n 个正整数组成的数组和一个正整数 s ,请找出该数组中满足其和 ≥ s 的最小长度子数组。如果无解,则返回 0。
6 | *
7 | * 样例:
8 | * 给定数组 [2,3,1,2,4,3] 和 s = 7, 子数组 [4,3] 是该条件下的最小长度子数组。
9 | */
10 | public class MinSubArrayLen {
11 | public int minSubArrayLen(int s, int[] nums) {
12 | if (nums == null || nums.length == 0) {
13 | return 0;
14 | }
15 | int minlen = Integer.MAX_VALUE;
16 | int start = 0;
17 | int end = 0;
18 | int sum = 0;
19 | int length = nums.length;
20 | while (end < length) {
21 | sum += nums[end++];
22 | while (sum >= s) {
23 | minlen = (end - start) < minlen ? (end - start) : minlen;
24 | sum -= nums[start++];
25 | }
26 | }
27 |
28 | return minlen == Integer.MAX_VALUE ? 0 : minlen;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N01Find.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/19
6 | * Time: 10:54
7 | *
8 | * 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,
9 | * 每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
10 | */
11 |
12 | public class N01Find {
13 | public boolean Find(int target, int[][] array) {
14 | if(array == null || array.length == 0){
15 | return false;
16 | }
17 |
18 | int row = array.length;
19 | int col = array[0].length;
20 | int posX = 0;
21 | int posY = col - 1;
22 |
23 | //从右上角往左下角找
24 | while (posX < row && posY >= 0) {
25 | if (array[posX][posY] == target) {
26 | return true;
27 | }
28 | if (array[posX][posY] > target) {
29 | posY--;
30 | } else {
31 | posX++;
32 | }
33 | }
34 | return false;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N02ReplaceSpace.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
5 | */
6 |
7 | public class N02ReplaceSpace {
8 | public String replaceSpace(StringBuffer str) {
9 |
10 | int p1 = str.length()-1;
11 |
12 | for (int i = 0; i <= p1 ; i++) {
13 | if(str.charAt(i) == ' '){
14 | str.append(" ");
15 | }
16 | }
17 | int p2 = str.length()-1;
18 | for (int i = p1; i >= 0; i--) {
19 | char c = str.charAt(p1--);
20 | if(c == ' '){
21 | str.setCharAt(p2--,'0');
22 | str.setCharAt(p2--,'2');
23 | str.setCharAt(p2--,'%');
24 | }else {
25 | str.setCharAt(p2--,c);
26 | }
27 | }
28 | return str.toString();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N03PrintListFromTailToHead.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 | import org.junit.Test;
5 |
6 | import java.util.ArrayList;
7 |
8 | /**
9 | * Author 范群松.
10 | * Date:2018/8/19
11 | * Time: 11:17
12 | * 从头到尾打印链表
13 | */
14 | public class N03PrintListFromTailToHead {
15 | ArrayList result = new ArrayList();
16 |
17 | @Test
18 | public void test(){
19 | ListNode listNode = new ListNode(1);
20 | listNode.next = new ListNode(2);
21 | listNode.next.next = new ListNode(3);
22 | listNode.next.next.next = new ListNode(4);
23 | printListFromTailToHead(listNode);
24 | }
25 |
26 |
27 | public ArrayList printListFromTailToHead(ListNode listNode) {
28 | if (listNode != null){
29 | printListFromTailToHead(listNode.next);
30 | result.add(listNode.val);
31 | }
32 | return result;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N04ReConstructBinaryTree.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | /**
6 | * created by reedfan on 2019/5/6 0006
7 | */
8 | public class N04ReConstructBinaryTree {
9 | /**
10 | *输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
11 | * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
12 | * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
13 | * 则重建二叉树并返回
14 | */
15 | public TreeNode reConstructBinaryTree(int [] pre, int [] in) {
16 | return reConBtree(pre,0,pre.length-1,in,0,in.length-1);
17 |
18 | }
19 |
20 | private TreeNode reConBtree(int[] pre, int preStart, int preEnd, int[] in, int inStart, int inEnd) {
21 |
22 | if(preStart>preEnd ||inStart>inEnd){
23 | return null;
24 | }
25 | //根节点
26 | TreeNode root = new TreeNode(pre[preStart]);
27 |
28 | for (int i = inStart; i <= inEnd ; i++) {
29 | if(pre[preStart] == in[i]){
30 | //重构左子树
31 | root.left = reConBtree(pre,preStart+1,preStart+i-inStart,in,inStart,i-1);
32 | //重构右子树
33 | root.right = reConBtree(pre,preStart+i+1-inStart,preEnd,in,i+1,inEnd);
34 | break;
35 |
36 | }
37 |
38 | }
39 | return root;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N05PushPop.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/19
8 | * Time: 14:17
9 | * 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
10 | */
11 |
12 | public class N05PushPop {
13 | //存储
14 | Stack stack1 = new Stack();
15 | //往外弹
16 | Stack stack2 = new Stack();
17 |
18 | public void push(int node) {
19 | stack1.push(node);
20 | }
21 |
22 | public int pop() {
23 | if (stack1.empty() && stack2.empty()) {
24 | throw new RuntimeException("Queue is empty!");
25 | }
26 |
27 | //一次性全部倒完
28 | if (stack2.empty()) {
29 | while (!stack1.empty()) {
30 | stack2.push(stack1.pop());
31 | }
32 | }
33 | return stack2.pop();
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N07Fibonacci.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | public class N07Fibonacci {
4 | public int fibonacci(int n) {
5 | if (n == 0) {
6 | return 0;
7 | }
8 | if (n == 1) {
9 | return 1;
10 | }
11 | int a = 0;
12 | int b = 1;
13 | int c = -1;
14 | for (int i = 2; i <= n; i++) {
15 | c = a + b;
16 | a = b;
17 | b = c;
18 | }
19 | return c;
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N08JumpFloor.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * 一只青蛙一次可以跳上1级台阶,也可以跳上2级。
5 | * 求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
6 | */
7 |
8 | public class N08JumpFloor {
9 | public int JumpFloor(int target) {
10 | if (target == 1) {
11 | return 1;
12 | }
13 |
14 | if (target == 2) {
15 | return 2;
16 | }
17 | int first = 1;
18 | int second = 2;
19 | int third = 0;
20 | for (int i = 3; i <= target; i++) {
21 | third = first + second;
22 | first = second;
23 | second = third;
24 | }
25 | return third;
26 |
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N10RectCover.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
5 | * 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
6 | */
7 |
8 | public class N10RectCover {
9 |
10 | public int JumpFloor(int target) {
11 | if (target == 1) {
12 | return 1;
13 | }
14 |
15 | if (target == 2) {
16 | return 2;
17 | }
18 | int first = 1;
19 | int second = 2;
20 | int third = 0;
21 | for (int i = 3; i <= target; i++) {
22 | third = first + second;
23 | first = second;
24 | second = third;
25 | }
26 | return third;
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N11NumberOf1.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
5 | */
6 | public class N11NumberOf1 {
7 |
8 | /*
9 |
10 | 0111
11 | & 0110
12 | 0110
13 |
14 | n n-1
15 |
16 |
17 | 0110
18 | & 0101
19 | 0100
20 |
21 |
22 | 0111 0110 去掉最后一个1
23 | */
24 |
25 |
26 | public int NumberOf1(int n) {
27 | int count = 0;
28 | while (n != 0) {
29 | n = n & (n - 1);
30 | count++;
31 | }
32 | return count;
33 | }
34 |
35 |
36 | /*
37 |
38 | 12 1
39 |
40 | 10进制
41 |
42 |
43 | 121 % 10 = 1
44 |
45 | 121 / 10 = 12
46 |
47 | */
48 |
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N14FindKthToTail.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 |
5 | /**
6 | * 输入一个链表,输出该链表中倒数第k个结点。
7 | */
8 |
9 | /*
10 | 1-2-3-4-5
11 |
12 | fast 前进k
13 | slow
14 | */
15 | public class N14FindKthToTail {
16 | public ListNode FindKthToTail(ListNode head, int k) {
17 | int count = 0;
18 | ListNode p = head;
19 | while (p != null){
20 | p = p.next;
21 | count ++;
22 | }
23 | if(count < k){
24 | return null;
25 | }
26 |
27 |
28 | ListNode p1 = head;
29 | ListNode p2 = head;
30 | for (int i = 0; i < k; i++) {
31 | p2 = p2.next;
32 | }
33 | while (p2 != null){
34 | p1 = p1.next;
35 | p2 = p2.next;
36 | }
37 | return p1;
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N15ReverseList.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 |
5 | /**
6 | * 输入一个链表,反转链表后,输出新链表的表头。
7 | *
8 | *
9 | */
10 |
11 | /*
12 | head
13 | 1-> 2 3 4 5
14 |
15 | */
16 |
17 | public class N15ReverseList {
18 | public ListNode ReverseList1(ListNode head) {
19 | ListNode pre = null;
20 | ListNode next = null;
21 | while (head != null) {
22 | //1. 保存next
23 | next = head.next;
24 | head.next = pre;
25 | pre = head;
26 | head = next;
27 |
28 | }
29 | return pre;
30 |
31 | }
32 |
33 |
34 | public ListNode ReverseList(ListNode head) {
35 | if(head == null || head.next == null){
36 | return head;
37 | }
38 | ListNode next = ReverseList(head.next);
39 | head.next.next = head;
40 | head.next = null;
41 | return next;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N16Merge.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 |
5 | public class N16Merge {
6 | public ListNode merge1(ListNode l1, ListNode l2) {
7 | if (l1 == null) {
8 | return l2;
9 | }
10 | if (l2 == null) {
11 | return l1;
12 | }
13 | ListNode tmp = new ListNode(0);
14 | ListNode res = tmp;
15 | while (l1 != null && l2 != null) {
16 | if (l1.val < l2.val) {
17 | tmp.next = l1;
18 | l1 = l1.next;
19 | } else {
20 | tmp.next = l2;
21 | l2 = l2.next;
22 |
23 | }
24 | tmp = tmp.next;
25 | }
26 |
27 | while (l1 != null) {
28 | tmp.next = l1;
29 | l1 = l1.next;
30 | tmp = tmp.next;
31 | }
32 |
33 | while (l2 != null) {
34 | tmp.next = l2;
35 | l2 = l2.next;
36 | tmp = tmp.next;
37 | }
38 | return res.next;
39 | }
40 |
41 | //递归写法
42 | public ListNode Merge(ListNode l1, ListNode l2) {
43 | if (l1 == null) {
44 | return l2;
45 | }
46 | if (l2 == null) {
47 | return l1;
48 | }
49 | if(l1.val stack = new Stack();
12 | //用来存储最小数
13 | Stack minStack = new Stack();
14 |
15 | public void push(int node) {
16 | stack.push(node);
17 | if (minStack.isEmpty() || minStack.peek() > node) {
18 | minStack.push(node);
19 | } else {
20 | minStack.push(minStack.peek());
21 | }
22 | }
23 |
24 | public void pop() {
25 | stack.pop();
26 | minStack.pop();
27 | }
28 |
29 | public int top() {
30 | return stack.peek();
31 | }
32 |
33 | public int min() {
34 | return minStack.peek();
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N21IsPopOrder.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/18
8 | * Time: 16:15
9 | * 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
10 | * 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,
11 | * 序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
12 | * (注意:这两个序列的长度是相等的)
13 | *
14 | *
15 | * 1,2,3,4,5
16 | *
17 | *
18 | *
19 | * stack
20 | *
21 | *
22 | *
23 | *
24 | *
25 | *
26 | *
27 | */
28 |
29 | public class N21IsPopOrder {
30 | public static void main(String[] args) {
31 | int[] pushA = {1,2,3,4,5};
32 | int[] popA = {4,5,3,2,1};
33 | System.out.println(IsPopOrder(pushA,popA));
34 | }
35 | public static boolean IsPopOrder(int [] pushA,int [] popA) {
36 | Stack stack = new Stack();
37 | int index = 0;
38 | for (int i = 0; i < pushA.length; i++) {
39 | stack.push(pushA[i]);
40 | while (!stack.isEmpty()&&stack.peek() == popA[index]){
41 | index++;
42 | stack.pop();
43 | }
44 | }
45 | return stack.isEmpty();
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N22PrintFromTopToBottom.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | import java.util.ArrayList;
6 | import java.util.LinkedList;
7 |
8 | /**
9 | * Author 范群松.
10 | * Date:2018/8/18
11 | * Time: 19:10
12 | * 从上往下打印出二叉树的每个节点,同层节点从左至右打印。
13 | */
14 |
15 | public class N22PrintFromTopToBottom {
16 | public ArrayList PrintFromTopToBottom(TreeNode root) {
17 | ArrayList result = new ArrayList();
18 | if(root == null){
19 | return result;
20 | }
21 | LinkedList list = new LinkedList<>();
22 | list.add(root);
23 | while (! list.isEmpty()){
24 | TreeNode first = list.remove(0);
25 | result.add(first.val);
26 | if(first.left != null){
27 | list.add(first.left);
28 | }
29 | if(first.right != null){
30 | list.add(first.right);
31 | }
32 | }
33 | return result;
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N23VerifySquenceOfBST.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/18
6 | * Time: 19:38
7 | * 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
8 | * 如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
9 | */
10 |
11 | public class N23VerifySquenceOfBST {
12 | public static void main(String[] args) {
13 | int[] array = {4, 6, 7, 5};
14 | System.out.println(new N23VerifySquenceOfBST().VerifySquenceOfBST(array));
15 | }
16 |
17 | /*
18 | 后续遍历 左右根
19 | 左子树小于根 右子树大于根
20 | */
21 | public boolean VerifySquenceOfBST(int[] sequence) {
22 | if (sequence.length == 0) {
23 | return false;
24 | }
25 | return isBST(sequence, 0, sequence.length - 1);
26 | }
27 |
28 |
29 | private boolean isBST(int[] arr, int start, int end) {
30 | //1.终止条件
31 | if (start >= end) {
32 | return true;
33 | }
34 |
35 |
36 | int i = start;
37 | for (; i < end; i++) {
38 | if (arr[i] > arr[end]) {
39 | break;
40 | }
41 | }
42 | for (int j = i; j < end; j++) {
43 | if (arr[j] < arr[end]) {
44 | return false;
45 | }
46 | }
47 | return isBST(arr, start, i - 1) && isBST(arr, i, end - 1);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N24FindPath.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | import java.util.ArrayList;
6 |
7 | /**
8 | * Author 范群松.
9 | * Date:2018/8/18
10 | * Time: 20:26
11 | * 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
12 | * 路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
13 | */
14 |
15 | public class N24FindPath {
16 | ArrayList> res = new ArrayList>();
17 | ArrayList list = new ArrayList();
18 |
19 | public ArrayList> FindPath(TreeNode root, int target) {
20 | if (root == null) {
21 | return res;
22 | }
23 | target -= root.val;
24 | list.add(root.val);
25 | if (root.left == null && root.right == null && target == 0) {
26 | res.add(new ArrayList(list));
27 | }
28 | FindPath(root.left, target);
29 | FindPath(root.right, target);
30 | list.remove(list.size() - 1);
31 | return res;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N28MoreThanHalfNum_Solution.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 |
4 | import java.util.HashMap;
5 | import java.util.Iterator;
6 | import java.util.Map;
7 |
8 | /**
9 | * Author 范群松.
10 | * Date:2018/8/27
11 | * Time: 20:21
12 | *
13 | * 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
14 | * 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,
15 | * 超过数组长度的一半,因此输出2。如果不存在则输出0。
16 | */
17 |
18 |
19 |
20 |
21 |
22 | public class N28MoreThanHalfNum_Solution {
23 |
24 |
25 |
26 | public int MoreThanHalfNum_Solution(int[] nums) {
27 | int a = nums[0];
28 | int cnta = 0;
29 | for (int num : nums) {
30 | if (num == a) {
31 | cnta++;
32 | continue;
33 | }
34 | if (cnta == 0) {
35 | a = num;
36 | cnta = 1;
37 | continue;
38 | }
39 | cnta--;
40 | }
41 |
42 | cnta = 0;
43 |
44 | for (int num : nums) {
45 | if (num == a) {
46 | cnta++;
47 | }
48 | }
49 | if (cnta <= nums.length / 2) {
50 | return 0;
51 | }
52 | return a;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N30FindGreatestSumOfSubArray.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/18
6 | * Time: 21:59
7 | * 连续子数组最大和
8 | */
9 |
10 | public class N30FindGreatestSumOfSubArray {
11 | public int FindGreatestSumOfSubArray(int[] array) {
12 | if (array.length == 0) {
13 | return 0;
14 | }
15 | int total = array[0];
16 | int max = array[0];
17 | for (int i = 1; i < array.length; i++) {
18 | if (total > 0) { //如果当前数据前面的total大于0,则total对数据有贡献
19 | total += array[i];
20 | } else {
21 | total = array[i]; //否则将当前值赋给total
22 | }
23 | if (max < total) {
24 | max = total; //total和max进行比较
25 | }
26 | }
27 | return max;
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N31NumberOf1Between1AndN_Solution.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | public class N31NumberOf1Between1AndN_Solution {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N32PrintMinNumber.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 |
4 | import java.util.Arrays;
5 | import java.util.Comparator;
6 |
7 | /**
8 | * Author 范群松.
9 | * Date:2018/8/19
10 | * Time: 10:16
11 | * 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
12 | * 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323
13 | */
14 |
15 | public class N32PrintMinNumber {
16 | public String PrintMinNumber(int [] numbers) {
17 | if(numbers.length == 0){
18 | return "";
19 | }
20 | StringBuffer sb = new StringBuffer();
21 | String[] str = new String[numbers.length];
22 | for (int i = 0; i < numbers.length; i++) {
23 | str[i] = String.valueOf(numbers[i]);
24 | }
25 |
26 | Arrays.sort(str, new Comparator() {
27 | public int compare(String o1, String o2) {
28 | String c1 = o1 + o2;
29 | String c2 = o2 + o1;
30 | return c1.compareTo(c2);
31 | }
32 | });
33 | for (int i = 0; i < numbers.length; i++) {
34 | sb.append(str[i]);
35 | }
36 | return sb.toString();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N33UglyNumber.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | public class N33UglyNumber {
4 |
5 | public static void main(String[] args) {
6 | System.out.println(uglyNumber(7));
7 | }
8 |
9 | private static int uglyNumber(int n){
10 |
11 | int[] help = new int[n];
12 | help[0] = 1;
13 | int i2 = 0;
14 | int i3 = 0;
15 | int i5 = 0;
16 | int index = 1;
17 | while (index map = new HashMap();
12 | int time = 0;
13 | for (int i = 0; i < str.length(); i++) {
14 | if (map.containsKey(str.charAt(i))) {
15 | time = map.get(str.charAt(i));
16 | map.put(str.charAt(i), ++time);
17 | } else {
18 | map.put(str.charAt(i), 1);
19 | }
20 |
21 | }
22 | for (int i = 0; i < str.length(); i++) {
23 | if (map.get(str.charAt(i)) == 1) {
24 | return i;
25 | }
26 |
27 | }
28 | return -1;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N36FindFirstCommonNode.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/18
8 | * Time: 15:49
9 | * 输入两个链表,找出它们的第一个公共结点。
10 | */
11 | public class N36FindFirstCommonNode {
12 | public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
13 | int sum1 = findArrayLenth(pHead1);
14 | int sum2 = findArrayLenth(pHead2);
15 | int chaju = sum1-sum2;
16 | if(chaju >= 0){
17 | while (chaju > 0){
18 | pHead1 = pHead1.next;
19 | chaju --;
20 | }
21 | }else {
22 | while (chaju < 0){
23 | pHead2 = pHead2.next;
24 | chaju ++;
25 | }
26 | }
27 | while (pHead1 != null){
28 | if(pHead1 == pHead2){
29 | return pHead1;
30 | }else {
31 | pHead1 = pHead1.next;
32 | pHead2 = pHead2.next;
33 | }
34 | }
35 | return null;
36 |
37 | }
38 | private int findArrayLenth(ListNode listNode){
39 | int sum = 0;
40 | while (listNode!=null){
41 | sum ++;
42 | listNode = listNode.next;
43 | }
44 | return sum;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N38TreeDepth.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | public class N38TreeDepth {
6 | public int TreeDepth(TreeNode root) {
7 | if (root == null) {
8 | return 0;
9 | }
10 | return TreeDepth(root.left) > TreeDepth(root.right) ? TreeDepth(root.left) + 1 : TreeDepth(root.right) + 1;
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N39IsBalanced_Solution.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.tree.TreeNode;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/17
8 | * Time: 22:07
9 | * 输入一棵二叉树,判断该二叉树是否是平衡二叉树。
10 | */
11 |
12 | public class N39IsBalanced_Solution {
13 | public boolean IsBalanced_Solution(TreeNode root) {
14 | if(root == null){
15 | return true;
16 | }
17 | if(TreeDepth(root.left)-TreeDepth(root.right)>1 || TreeDepth(root.right)-TreeDepth(root.left)>1){
18 | return false;
19 | }
20 | return (IsBalanced_Solution(root.left)&&IsBalanced_Solution(root.right));
21 | }
22 |
23 | private int TreeDepth(TreeNode root){
24 | if(root == null){
25 | return 0;
26 | }
27 | int max = TreeDepth(root.left)>TreeDepth(root.right)?TreeDepth(root.left)+1:TreeDepth(root.right)+1;
28 | return max;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N40FindNumsAppearOnce.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | public class N40FindNumsAppearOnce {
4 | public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
5 | if (array.length == 2) {
6 | num1[0] = array[0];
7 | num2[0] = array[1];
8 | }
9 |
10 | //得到异或的结果
11 | int res = 0;
12 | for (int num : array) {
13 | res = res ^ num;
14 | }
15 | //寻找异或结果第一个不一样的数
16 | int index = findFirst1(res);
17 |
18 | for (int num : array) {
19 | if (indexKIs1(num, index)) {
20 | num1[0] ^= num;
21 |
22 | } else {
23 | num2[0] ^= num;
24 |
25 | }
26 | }
27 |
28 | }
29 |
30 | private int findFirst1(int res) {
31 | int index = 0;
32 | while (index < 32 && (res & 1) == 0) {
33 | index++;
34 | res >>= 1;
35 | }
36 | return index;
37 | }
38 |
39 | private boolean indexKIs1(int num, int index) {
40 | return ((num >> index) & 1) == 1;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/N42FindNumbersWithSum.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/17
8 | * Time: 21:21
9 | *
10 | 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,
11 | 如果有多对数字的和等于S,输出两个数的乘积最小的。
12 | 输出描述:
13 |
14 | 对应每个测试案例,输出两个数,小的先输出。
15 | */
16 | public class N42FindNumbersWithSum {
17 | public ArrayList FindNumbersWithSum(int [] array, int sum) {
18 | ArrayList list = new ArrayList();
19 | int start = 0;
20 | int end = array.length-1;
21 | while (start < end){
22 | if(array[start] + array[end] == sum){
23 | list.add(array[start]);
24 | list.add(array[end]);
25 | break;
26 | }else {
27 | if(array[start] + array[end] < sum){
28 | start ++;
29 | }else {
30 | end --;
31 | }
32 | }
33 | }
34 | return list;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Solution1.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/17
8 | * Time: 17:01
9 | * 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,
10 | * 返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
11 | */
12 | public class Solution1 {
13 | public ListNode deleteDuplication(ListNode pHead)
14 | {
15 | ListNode res = new ListNode(0);
16 | res.next = pHead;
17 | ListNode pre = res;
18 | ListNode cur = pHead;
19 | while (cur != null && cur.next != null){
20 | if(cur.val != cur.next.val){
21 | pre = cur;
22 | }else {
23 | while (cur.next != null && cur.val == cur.next.val){
24 | cur = cur.next;
25 | pre.next = cur.next;
26 | }
27 | }
28 | cur = cur.next;
29 | }
30 | return res.next;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Solution2.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import leetcode.arraylist.ListNode;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/17
8 | * Time: 17:43
9 | * 找到环的入口节点
10 | */
11 | public class Solution2 {
12 | public ListNode EntryNodeOfLoop(ListNode pHead) {
13 | ListNode fast = pHead;
14 | ListNode slow = pHead;
15 | while (fast!= null && fast.next != null){
16 | fast = fast.next.next;
17 | slow = slow.next;
18 | if(fast == slow){
19 | fast = pHead;
20 | while (fast != slow){
21 | fast = fast.next;
22 | slow = slow.next;
23 | }
24 | return fast;
25 | }
26 | }
27 | return null;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Solution222.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/20
8 | * Time: 21:05
9 | * 给定两个字符串A和B,同时给定两串的长度n和m。
10 | 测试样例:"1AB2345CD",9,"12345EF",7 返回:4
11 | */
12 |
13 | public class Solution222 {
14 |
15 | private static int longest(String A, int n, String B, int m) {
16 | int[][] dp=new int[n][m];
17 | int max = 0;
18 | for (int i = 0; i < n; i++) {
19 | for (int j = 0; j < m; j++) {
20 | dp[n][m] = 0;
21 | }
22 | }
23 | for (int i = 0; i < n; i++) {
24 | for (int j = 0; j < m; j++) {
25 | if(A.charAt(i) == B.charAt(j)){
26 | if(i == 0 || j == 0){
27 | dp[i][j] = 1;
28 | }else {
29 | dp[i][j] = dp[i-1][j-1] + 1;
30 | }
31 | max = dp[i][j]>max?dp[i][j]:max;
32 | }
33 |
34 | }
35 |
36 | }
37 | return max;
38 | }
39 |
40 | public static void main(String[] args) {
41 | Scanner sc = new Scanner(System.in);
42 | int N = Integer.parseInt(sc.nextLine());
43 | for (int i = 0; i < N; i++) {
44 | String str1 = sc.nextLine();
45 | String str2 = sc.nextLine();
46 | int str1len = str1.length();
47 | int str2len = str2.length();
48 | System.out.println(longest(str1, str1len, str2,str2len));
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Solution223.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/20
8 | * Time: 21:07
9 | */
10 |
11 | public class Solution223 {
12 | private static int num(int n) {
13 | if (n == 0) {
14 | return 0;
15 | }
16 | int[] numbers=new int[n+1];
17 | numbers[0]=0;
18 | numbers[1]=1;
19 | for (int i = 2; i <= n; i++) {
20 | numbers[i]=numbers[i-1]+numbers[i-2];
21 | }
22 | return numbers[n];
23 | }
24 | public static void main(String [] args) {
25 | Scanner scanner=new Scanner(System.in);
26 | int n= scanner.nextInt();
27 | for (int i = 0; i =i ; k--) {
39 | array[k+1] = array[k];
40 | }
41 | array[i++] = firstodd;
42 |
43 | }else {
44 | break;
45 | }
46 |
47 | }
48 | }
49 |
50 |
51 | private static Boolean isEven(int num){
52 | if(num%2 == 0){
53 | return true;
54 | }
55 | return false;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Solution23.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | /**
7 | * Author 范群松.
8 | * Date:2018/8/17
9 | * Time: 21:44
10 | */
11 |
12 | public class Solution23 {
13 | public boolean duplicate(int numbers[],int length,int [] duplication) {
14 | if (length == 0){
15 | return false;
16 | }
17 | Set set = new HashSet();
18 | for (int i = 0; i < length; i++) {
19 | Boolean bool = set.add(numbers[i]);
20 | if(! bool){
21 | duplication[0] = numbers[i];
22 | return true;
23 | }
24 | }
25 | return false;
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/Solution29.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/25
6 | * Time: 13:42
7 | */
8 |
9 | public class Solution29 {
10 |
11 | public static void main(String[] args) {
12 | int a[][] = new int[4][4];
13 | int b[][] = new int[4][4];
14 | int k = 0;
15 | for (int i = 0; i < 4; i++) {
16 | for (int j = 0; j < 4; j++) {
17 | a[i][j] = k++;
18 | }
19 |
20 | }
21 | for (int i = 0; i < 4; i++) {
22 | for (int j = 0; j < 4; j++) {
23 | b[3-j][i] = a[i][j];
24 | }
25 | }
26 |
27 | for (int i = 0; i < 4; i++) {
28 | for (int j = 0; j < 4; j++) {
29 | System.out.println(b[i][j]);
30 | }
31 | }
32 |
33 | }
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/jianzhioffer/TwoNum.java:
--------------------------------------------------------------------------------
1 | package jianzhioffer;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * created by reedfan on 2019/4/25 0025
8 | */
9 | public class TwoNum {
10 | public static void main(String[] args) {
11 | int[] numbers = { 7,2, 11, 15};
12 | int[] twoSum = twoSum(numbers,9);
13 | System.out.println(twoSum[1]);
14 |
15 | }
16 | public static int[] twoSum(int[] numbers, int target) {
17 | int[] res = new int[2];
18 | Map hashMap = new HashMap();
19 |
20 | for(int i = 0;i futureTask = new FutureTask(new Callable() {
17 | @Override
18 | public Integer call() throws Exception {
19 | int result = 0;
20 | for (int i = 0; i < 100; i++) {
21 | Thread.sleep(30);
22 | result += i;
23 | }
24 | return result;
25 | }
26 | });
27 |
28 | Thread computeThread = new Thread(futureTask);
29 | computeThread.start();
30 |
31 | //此时可以去干其他的事情
32 | System.out.println("other task is running...");
33 | Thread.sleep(3000);
34 |
35 | System.out.println(System.currentTimeMillis()-t1);
36 | System.out.println(futureTask.get());
37 | System.out.println(System.currentTimeMillis()-t1);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/juc/TestCopyOnWriteArrayList.java:
--------------------------------------------------------------------------------
1 | package juc;
2 |
3 | import java.util.Iterator;
4 | import java.util.concurrent.CopyOnWriteArrayList;
5 |
6 | /*
7 | * CopyOnWriteArrayList/CopyOnWriteArraySet : “写入并复制”
8 | * 注意:添加操作多时,效率低,因为每次添加时都会进行复制,开销非常的大。并发迭代操作多时可以选择。
9 | */
10 | public class TestCopyOnWriteArrayList {
11 |
12 | public static void main(String[] args) {
13 | HelloThread ht = new HelloThread();
14 |
15 | for (int i = 0; i < 10; i++) {
16 | new Thread(ht).start();
17 | }
18 | }
19 |
20 | }
21 |
22 | class HelloThread implements Runnable{
23 |
24 | // private static List list = Collections.synchronizedList(new ArrayList());
25 |
26 | private static CopyOnWriteArrayList list = new CopyOnWriteArrayList<>();
27 |
28 | static{
29 | list.add("AA");
30 | list.add("BB");
31 | list.add("CC");
32 | }
33 |
34 | public void run() {
35 |
36 | Iterator it = list.iterator();
37 |
38 | while(it.hasNext()){
39 | System.out.println(it.next());
40 |
41 | list.add("AA");
42 | }
43 |
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/juc/TestVolatile.java:
--------------------------------------------------------------------------------
1 | package juc;
2 |
3 |
4 | /**
5 | * 一、volatile 关键字:当多个线程进行操作共享数据时,可以保证内存中的数据可见。
6 | * 相较于 synchronized 是一种较为轻量级的同步策略。
7 | *
8 | * 注意:
9 | * 1. volatile 不具备“互斥性”
10 | * 2. volatile 不能保证变量的“原子性”
11 | */
12 | public class TestVolatile {
13 | public static void main(String[] args) {
14 | ThreadDeMo td = new ThreadDeMo();
15 | new Thread(td).start();
16 |
17 | while (true){
18 | if(td.isFlag()){
19 | System.out.println("------------------");
20 | break;
21 | }
22 | }
23 | }
24 |
25 | }
26 |
27 | class ThreadDeMo implements Runnable{
28 | //不加volatile,将不会强制从主存读取数据,主程序读到的flag一直是false
29 | //将会一直阻塞住
30 | private volatile boolean flag = false;
31 |
32 | public boolean isFlag() {
33 | return flag;
34 | }
35 |
36 | public void setFlag(boolean flag) {
37 | this.flag = flag;
38 | }
39 |
40 | public void run() {
41 | try {
42 | Thread.sleep(2000);
43 | } catch (InterruptedException e) {
44 | e.printStackTrace();
45 | }
46 | flag = true;
47 | System.out.println("flag="+flag);
48 |
49 | }
50 | }
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/BubbleSort.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/8/23
8 | * Time: 20:11
9 | */
10 |
11 | public class BubbleSort {
12 | public static void main(String[] args) {
13 | Random random = new Random(5);
14 | int[] score = new int[5];
15 | for (int i = 0; i < 5; i++) {
16 | score[i] = random.nextInt(100);
17 | }
18 | for (int i = 0; i < score.length-1; i++) {
19 | for (int j = 0; j < score.length-1-i; j++) {
20 | if(score[j] > score[j+1]){
21 | int temp = score[j];
22 | score[j] = score[j+1];
23 | score[j+1] = temp;
24 | }
25 | }
26 | }
27 |
28 | for (int i = 0; i < score.length; i++) {
29 | System.out.println(score[i]);
30 | }
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/Duplicate.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
5 | */
6 |
7 | public class Duplicate {
8 | public boolean duplicate(int numbers[],int length,int [] duplication) {
9 | if(numbers == null || numbers.length < 2 || length <2){
10 | return false;
11 | }
12 |
13 | for (int i = 0; i < length; i++) {
14 | while (numbers[i] != i){
15 | if(numbers[i] == numbers[numbers[i]]){
16 | duplication[0] = numbers[i];
17 | return true;
18 | }else {
19 | swap(numbers,i,numbers[i]);
20 |
21 | }
22 | }
23 |
24 | }
25 | return false;
26 |
27 | }
28 |
29 | private void swap(int[] nums, int i, int j){
30 | int tmp = nums[i];
31 | nums[i] = nums[j];
32 | nums[j] = tmp;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/EFCZ.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/23
6 | * Time: 20:22
7 | */
8 |
9 | public class EFCZ {
10 |
11 | public static void main(String[] args) {
12 | int[] a = {1,2,3,4,5,6,7,8,9};
13 | int value = binary(a,9);
14 | System.out.println(value);
15 | }
16 |
17 |
18 |
19 | public static int binary(int[] array,int vale){
20 | int low = 0;
21 | int high = array.length-1;
22 | while (low <= high){
23 |
24 | int middle = low +(high - low)/2;
25 | if(vale == array[middle]){
26 | return middle;
27 | }
28 | if(vale > array[middle]){
29 | low = middle+1;
30 | }
31 | if(vale < array[middle]){
32 | high = middle-1;
33 | }
34 | }
35 | return -1;
36 | }
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/Find.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * created by reedfan on 2019/4/25 0025
5 | * 在一个二维数组中(每个一维数组的长度相同),
6 | * 每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
7 | * 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
8 | */
9 | public class Find {
10 | public boolean find(int target, int [][] array) {
11 | int hang = array.length;
12 | int lie = array[0].length;
13 |
14 | int i = 0;
15 | int j = lie-1;
16 |
17 | while (i=0){
18 | if(array[i][j] == target){
19 | return true;
20 | }else {
21 | if(array[i][j] < target){
22 | i++;
23 | }else {
24 | j--;
25 | }
26 | }
27 |
28 | }
29 | return false;
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/FindkthInArray.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 时间复杂度为O(n)
5 | * 复杂度:平均情况下,遍历一次数组找到哨兵是n,下一次就是n/2,最后到1,中间最多需要k次(k=lg2n)
6 | * 等比数列求和:n+n/2+n/4+n/8+…+1 = 2n
7 | */
8 |
9 | public class FindkthInArray {
10 |
11 | public static void main(String[] args) {
12 | int[] array = {3,3,3,3,4,3,3,3,3};
13 | System.out.println(findKthLargest(array,1));
14 | }
15 |
16 | public static int findKthLargest(int[] nums,int k){
17 | return findK(nums,k,0,nums.length-1);
18 | }
19 |
20 | private static int findK(int[] nums, int k, int start, int end) {
21 |
22 | int low = start;
23 | int high = end;
24 | int key = nums[low];
25 | while (low=key){
28 | high --;
29 | }
30 | nums[low] = nums[high];
31 | while (lowk-1){
41 | return findK(nums, k, start, low-1);
42 | }else {
43 | return findK(nums, k, low+1, end);
44 | }
45 |
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/Manacher.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | public class Manacher {
4 |
5 | public int maxLcpsLength(String str){
6 | if(str == null ||str.length() == 0){
7 | return 0;
8 | }
9 | char[] charArr = manacherString(str);
10 |
11 | int len = charArr.length;
12 | //最近一个PR更新时,那个回文中心的位置。
13 | int index = -1;
14 | //之前遍历的所有的字符的所有回文半径中,最右即将到达的位置初始化为-1
15 | int pR = -1;
16 | //pArr[i]表示以i位置作为回文中心,阔出去能得到的最大的回文半径
17 | int[] pArr = new int[charArr.length];
18 | int max = Integer.MIN_VALUE;
19 |
20 | for (int i = 0; i != len ; i++) {
21 |
22 |
23 | }
24 |
25 | return max-1;
26 |
27 |
28 |
29 | }
30 |
31 |
32 |
33 | public char[] manacherString(String str){
34 | char[] charArr = str.toCharArray();
35 | char[] res = new char[str.length()*2+1];
36 | int index = 0;
37 | for (int i = 0; i != res.length ; i++) {
38 | res[i] = (i&1)==0?'#':charArr[index++];
39 |
40 | }
41 | return res;
42 | }
43 |
44 |
45 |
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/MaxOneBorderSize.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | public class MaxOneBorderSize {
4 | public static int getMaxSize(int[][] m) {
5 |
6 | int[][] right = new int[m.length][m[0].length];
7 | int[][] down = new int[m.length][m[0].length];
8 | setBorderMap(m,right,down);
9 | return 0;
10 |
11 |
12 |
13 | }
14 | public static void setBorderMap(int[][] m, int[][] right, int[][] down) {
15 |
16 | int row = m.length;
17 | int col = m[0].length;
18 | if(m[row-1][col-1] == 1){
19 | right[row-1][col-1] = 1;
20 | down[row-1][col-1] = 1;
21 | }
22 | for (int i = row-2; i >=0 ; i--) {
23 | if(m[i][col-1]==1){
24 | right[i][col-1] = 1;
25 | }
26 |
27 | }
28 |
29 | for (int i = row-2; i >=0 ; i--) {
30 | for (int j = col-2; j >=0 ; j--) {
31 | if(m[i][j] == 1){
32 | right[i][j] = right[i][j+1] +1;
33 | down[i][j] = down[i+1][j]+1;
34 | }
35 |
36 | }
37 |
38 | }
39 |
40 |
41 |
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/MaxProduct.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * https://blog.csdn.net/qq_41231926/article/details/86261978
5 | */
6 | public class MaxProduct {
7 |
8 | public int maxProduct(int[] nums){
9 |
10 | int[] maxdp = new int[nums.length];
11 | int[] mindp = new int[nums.length];
12 | maxdp[0] = maxdp[0] = nums[0];
13 | for (int i = 1; i < nums.length ; i++) {
14 | if (nums[i] >= 0) {
15 | maxdp[i] = Math.max(maxdp[i - 1] * nums[i], nums[i]);
16 | mindp[i] = Math.min(mindp[i - 1] * nums[i], nums[i]);
17 | }else {
18 | maxdp[i] = Math.max(mindp[i - 1] * nums[i], nums[i]);
19 | mindp[i] = Math.min(maxdp[i - 1] * nums[i], nums[i]);
20 | }
21 | }
22 | int result = Integer.MIN_VALUE;
23 | for(int i = 0; i < maxdp.length ; i++){
24 | if(maxdp[i] > result){
25 | result = maxdp[i];
26 | }
27 | }
28 | return result;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/MaxSubArrayDemo.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 数组预处理
5 | */
6 | public class MaxSubArrayDemo {
7 |
8 | public static void main(String[] args) {
9 | int[][] array = {
10 | {0 ,-2 ,-7, 0},
11 | {9 ,2 ,-6 ,2},
12 | {-4 ,1 ,-4 ,1},
13 | {-1, 8 ,0 ,-2}
14 | };
15 | int row = array.length;
16 | int col = array[0].length;
17 | /*
18 | 从00开始
19 | */
20 | int[][] sum = new int[row][col];
21 | sum[0][0] = array[0][0];
22 | for (int i = 1; i < col; i++) {
23 | sum[i][0]=sum[i-1][0]+array[i][0];
24 | }
25 | for (int i = 1; i < row; i++) {
26 | sum[0][i] = sum[0][i-1]+array[0][i];
27 | }
28 | for (int i = 1; i < col ; i++) {
29 | for (int j = 1; j map = new HashMap<>();
29 | for (int i = 0; i < nums.length; i++) {
30 | int value = target - nums[i];
31 | if (map.containsKey(value)) {
32 | return new int[] { map.get(value), i };
33 | }
34 | map.put(nums[i], i);
35 | }
36 | return null;
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N042Trap.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
5 | *
6 | * 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。
7 | *
8 | * 示例:
9 | *
10 | * 输入: [0,1,0,2,1,0,1,3,2,1,2,1]
11 | * 输出: 6
12 | *
13 | * 来源:力扣(LeetCode)
14 | * 链接:https://leetcode-cn.com/problems/trapping-rain-water
15 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
16 | */
17 |
18 | public class N042Trap {
19 | /*对于每一根柱子上最后接的雨水。其结果应该是其左右两边高度的最小值,减去本柱子的高度。
20 | 举个例子,柱子高度为[2,1,5]。最后高度为1的柱子上盛放的雨水的高度应该为min(5,20)-1=1。
21 | 因此对于本题,我们只需要将每根柱子左右两边最大值的较小值减去自己,即可得到解。
22 | */
23 | public int trap(int[] height) {
24 |
25 | if(height == null || height.length < 3){
26 | return 0;
27 | }
28 | //left[i]表示第i列左边的最高的列值,包含第i列
29 | int[] left = new int[height.length];
30 |
31 | left[0] = height[0];
32 |
33 | for (int i = 1; i < height.length ; i++) {
34 | left[i] = left[i-1] > height[i]?left[i-1] : height[i];
35 | }
36 | //right[i]表示第i列右边的最高的列值,包含第i列
37 | int[] right = new int[height.length];
38 |
39 | right[height.length -1] = height[height.length-1];
40 |
41 | for (int i = height.length-2; i >= 0 ; i--) {
42 | right[i] = right[i+1] > height[i]?right[i+1] : height[i];
43 | }
44 | int sum = 0;
45 | for (int i = 1; i < height.length-1 ; i++) {
46 | sum += Math.min(left[i],right[i])-height[i];
47 | }
48 | return sum;
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N066PlusOne.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
5 | *
6 | * 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
7 | *
8 | * 你可以假设除了整数 0 之外,这个整数不会以零开头。
9 | *
10 | * 示例 1:
11 | *
12 | * 输入: [1,2,3]
13 | * 输出: [1,2,4]
14 | * 解释: 输入数组表示数字 123。
15 | *
16 | * 示例 2:
17 | *
18 | * 输入: [4,3,2,1]
19 | * 输出: [4,3,2,2]
20 | * 解释: 输入数组表示数字 4321。
21 | *
22 | * 来源:力扣(LeetCode)66
23 | * 链接:https://leetcode-cn.com/problems/plus-one
24 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
25 | */
26 | public class N066PlusOne {
27 | /*
28 | 从右向左,只要有一位没有进位。那后面的都不会有进位。
29 | 还有比如999这种情况,最后的结果为10000。只需要新建一个比当前数组大1位的数组。并且0位置为1即可。
30 |
31 | */
32 |
33 | public static void main(String[] args) {
34 | int[] digits = {8,8,9};
35 |
36 | System.out.println(plusOne(digits));
37 | }
38 | public static int[] plusOne(int[] digits) {
39 | for (int i = digits.length - 1; i >= 0; i--) {
40 | digits[i]++;
41 | digits[i] = digits[i] % 10;
42 | if (digits[i] != 0){
43 | return digits;
44 | }
45 | }
46 | digits = new int[digits.length + 1];
47 | digits[0] = 1;
48 | return digits;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N075SortColors.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
5 | *
6 | * 此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
7 | *
8 | * 注意:
9 | * 不能使用代码库中的排序函数来解决这道题。
10 | *
11 | * 示例:
12 | *
13 | * 输入: [2,0,2,1,1,0]
14 | * 输出: [0,0,1,1,2,2]
15 | *
16 | * 来源:力扣(LeetCode)
17 | * 链接:https://leetcode-cn.com/problems/sort-colors
18 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
19 | */
20 |
21 | public class N075SortColors {
22 |
23 | public static void main(String[] args) {
24 | int[] nums = {2, 0, 2, 1, 1, 0};
25 | new N075SortColors().sortColors(nums);
26 | }
27 | /*
28 | 因为本题数据样本仅为3种数字。所以我们可以建一个空间为3的数组,表示每种数字出现的次数。
29 | 最后从小到大。将每种数字赋值的原数组中。
30 | */
31 |
32 | public void sortColors(int[] nums) {
33 | if (nums == null || nums.length == 0) {
34 | return;
35 | }
36 | int[] tmp = new int[3];
37 | for (int num : nums) {
38 | tmp[num]++;
39 | }
40 | for (int i = 0; i < nums.length; i++) {
41 | if (tmp[0]-- > 0) {
42 | nums[i] = 0;
43 | } else {
44 | if (tmp[1]-- > 0) {
45 | nums[i] = 1;
46 | } else {
47 | nums[i] = 2;
48 | }
49 | }
50 |
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N080merge.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
5 | *
6 | * 说明:
7 | *
8 | * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
9 | * 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
10 | *
11 | * 示例:
12 | *
13 | * 输入:
14 | * nums1 = [1,2,3,0,0,0], m = 3
15 | * nums2 = [2,5,6], n = 3
16 | *
17 | * 输出: [1,2,2,3,5,6]
18 | *
19 | * 来源:力扣(LeetCode)
20 | * 链接:https://leetcode-cn.com/problems/merge-sorted-array
21 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22 | */
23 | public class N080merge {
24 |
25 | /*
26 | 从右往左排序,指定三个坐标pos = m + n - 1(最终被排在哪个位置)
27 | s1 = m - 1(nums1的最右端), s2 = n-1(nums2的最右端)。
28 | 两个数组均从右向左比较,较大的放到pos位置。
29 |
30 |
31 | */
32 |
33 | public void merge(int[] nums1, int m, int[] nums2, int n) {
34 | int pos = m + n - 1;
35 | int s1 = m - 1;
36 | int s2 = n - 1;
37 | while (s1 >= 0 && s2 >= 0) {
38 | if (nums1[s1] >= nums2[s2]) {
39 | nums1[pos--] = nums1[s1--];
40 | } else {
41 | nums1[pos--] = nums2[s2--];
42 | }
43 | }
44 | while (s1 >= 0) {
45 | nums1[pos--] = nums1[s1--];
46 | }
47 | while (s2 >= 0) {
48 | nums1[pos--] = nums2[s2--];
49 | }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N118Generate.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
8 | *
9 | * 在杨辉三角中,每个数是它左上方和右上方的数的和。
10 | *
11 | * 示例:
12 | *
13 | * 输入: 5
14 | * 输出:
15 | * [
16 | * [1],
17 | * [1,1],
18 | * [1,2,1],
19 | * [1,3,3,1],
20 | * [1,4,6,4,1]
21 | * ]
22 | *
23 | * 来源:力扣(LeetCode) 118
24 | * 链接:https://leetcode-cn.com/problems/pascals-triangle
25 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
26 | */
27 |
28 | public class N118Generate {
29 | public static void main(String[] args) {
30 | new N118Generate().generate(5);
31 | }
32 | public List> generate(int numRows) {
33 | List> lists = new ArrayList<>();
34 | if(numRows <=0){
35 | return lists;
36 | }
37 | List list = new ArrayList<>();
38 | list.add(1);
39 | lists.add(list);
40 | if(numRows == 1){
41 | return lists;
42 | }
43 | for (int i = 2; i <= numRows ; i++) {
44 | ListnewList = new ArrayList<>();
45 | newList.add(1);
46 | for (int j = 1; j < i-1 ; j++) {
47 | newList.add(list.get(j-1)+list.get(j));
48 | }
49 | newList.add(1);
50 | lists.add(new ArrayList<>(newList));
51 | list = newList;
52 | }
53 |
54 | return lists;
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N219containsNearbyDuplicate.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import java.util.HashMap;
4 | import java.util.HashSet;
5 | import java.util.Map;
6 | import java.util.Set;
7 |
8 | public class N219containsNearbyDuplicate {
9 |
10 | /*
11 | 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值最大为 k。
12 |
13 | 示例 1:
14 |
15 | 输入: nums = [1,2,3,1], k = 3
16 | 输出: true
17 |
18 | 示例 2:
19 |
20 | 输入: nums = [1,0,1,1], k = 1
21 | 输出: true
22 |
23 | 示例 3:
24 |
25 | 输入: nums = [1,2,3,1,2,3], k = 2
26 | 输出: false
27 |
28 | 来源:力扣(LeetCode)
29 | 链接:https://leetcode-cn.com/problems/contains-duplicate-ii
30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
31 | */
32 |
33 |
34 | /*
35 | 类似于滑动窗口,里面只存储k个元素
36 | */
37 | public boolean containsNearbyDuplicate(int[] nums, int k) {
38 | if (nums == null || nums.length < 2 || k < 1) {
39 | return false;
40 | }
41 | Set set = new HashSet<>();
42 |
43 | for (int i = 0; i < nums.length; i++) {
44 | if (set.contains(nums[i])) {
45 | return true;
46 | }
47 | if (i - k >= 0) {
48 | set.remove(nums[i - k]);
49 | }
50 | set.add(nums[i]);
51 |
52 | }
53 | return false;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N240searchMatrix.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
5 | *
6 | * 每行的元素从左到右升序排列。
7 | * 每列的元素从上到下升序排列。
8 | *
9 | * 示例:
10 | *
11 | * 现有矩阵 matrix 如下:
12 | *
13 | * [
14 | * [1, 4, 7, 11, 15],
15 | * [2, 5, 8, 12, 19],
16 | * [3, 6, 9, 16, 22],
17 | * [10, 13, 14, 17, 24],
18 | * [18, 21, 23, 26, 30]
19 | * ]
20 | *
21 | * 给定 target = 5,返回 true。
22 | *
23 | * 给定 target = 20,返回 false。
24 | *
25 | * 来源:力扣(LeetCode)
26 | * 链接:https://leetcode-cn.com/problems/search-a-2d-matrix-ii
27 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
28 | */
29 | public class N240searchMatrix {
30 |
31 | public static void main(String[] args) {
32 | int[][] matrix = {{1,1}};
33 | new N240searchMatrix().searchMatrix(matrix,2);
34 | }
35 |
36 |
37 | public boolean searchMatrix(int[][] matrix, int target) {
38 | if(matrix == null || matrix.length == 0){
39 | return false;
40 | }
41 | int row = matrix.length;
42 | int col = matrix[0].length;
43 | int posX = 0;
44 | int posY = col - 1;
45 | //从右上角往左下角找
46 | while (posX < row && posY >= 0) {
47 | if (matrix[posX][posY] == target) {
48 | return true;
49 | }
50 | if (matrix[posX][posY] > target) {
51 | posY--;
52 | } else {
53 | posX++;
54 | }
55 | }
56 | return false;
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N258addDigits.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
5 | *
6 | * 示例:
7 | *
8 | * 输入: 38
9 | * 输出: 2
10 | * 解释: 各位相加的过程为:3 + 8 = 11, 1 + 1 = 2。 由于 2 是一位数,所以返回 2。
11 | *
12 | * 进阶:
13 | * 你可以不使用循环或者递归,且在 O(1) 时间复杂度内解决这个问题吗?
14 | *
15 | * 来源:力扣(LeetCode)
16 | * 链接:https://leetcode-cn.com/problems/add-digits
17 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
18 | */
19 | public class N258addDigits {
20 | public int addDigits(int num) {
21 |
22 | return 0;
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N263isUgly.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 编写一个程序判断给定的数是否为丑数。
8 | *
9 | * 丑数就是只包含质因数 2, 3, 5 的正整数。
10 | *
11 | * 示例 1:
12 | *
13 | * 输入: 6
14 | * 输出: true
15 | * 解释: 6 = 2 × 3
16 | *
17 | * 示例 2:
18 | *
19 | * 输入: 8
20 | * 输出: true
21 | * 解释: 8 = 2 × 2 × 2
22 | *
23 | * 示例 3:
24 | *
25 | * 输入: 14
26 | * 输出: false
27 | * 解释: 14 不是丑数,因为它包含了另外一个质因数 7。
28 | *
29 | * 说明:
30 | *
31 | * 1 是丑数。
32 | * 输入不会超过 32 位有符号整数的范围: [−231, 231 − 1]。
33 | *
34 | * 来源:力扣(LeetCode)
35 | * 链接:https://leetcode-cn.com/problems/ugly-number
36 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
37 | */
38 | public class N263isUgly {
39 | public static void main(String[] args) {
40 | System.out.println(new N263isUgly().isUgly(14));
41 | }
42 |
43 | public boolean isUgly(int num) {
44 | if(num == 0){
45 | return false;
46 | }
47 |
48 | while (num != 1){
49 | if(num % 2 == 0){
50 | num /= 2;
51 | continue;
52 | }
53 | if(num % 3 == 0){
54 | num /= 3;
55 | continue;
56 | }
57 | if(num % 5 == 0){
58 | num /= 5;
59 | continue;
60 | }
61 | return false;
62 | }
63 |
64 | return true;
65 |
66 |
67 |
68 |
69 |
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N283moveZeroes.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
5 | *
6 | * 示例:
7 | *
8 | * 输入: [0,1,0,3,12]
9 | * 输出: [1,3,12,0,0]
10 | *
11 | * 说明:
12 | *
13 | * 必须在原数组上操作,不能拷贝额外的数组。
14 | * 尽量减少操作次数。
15 | *
16 | * 来源:力扣(LeetCode)
17 | * 链接:https://leetcode-cn.com/problems/move-zeroes
18 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
19 | */
20 | public class N283moveZeroes {
21 | public static void main(String[] args) {
22 | int[] nums = {0, 1, 0, 3, 12};
23 | new N283moveZeroes().moveZeroes(nums);
24 | }
25 |
26 | public void moveZeroes(int[] nums) {
27 | int cnt = 0;
28 | for (int i = 0; i < nums.length; i++) {
29 | if (nums[i] == 0) {
30 | cnt++;
31 | } else {
32 | nums[i - cnt] = nums[i];
33 | }
34 | }
35 | for (int i = nums.length - cnt; i < nums.length; i++) {
36 | nums[i] = 0;
37 | }
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N287findDuplicate.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
5 | *
6 | * 示例 1:
7 | *
8 | * 输入: [1,3,4,2,2]
9 | * 输出: 2
10 | *
11 | * 示例 2:
12 | *
13 | * 输入: [3,1,3,4,2]
14 | * 输出: 3
15 | *
16 | * 说明:
17 | *
18 | * 不能更改原数组(假设数组是只读的)。
19 | * 只能使用额外的 O(1) 的空间。
20 | * 时间复杂度小于 O(n2) 。
21 | * 数组中只有一个重复的数字,但它可能不止重复出现一次。
22 | *
23 | * 来源:力扣(LeetCode)
24 | * 链接:https://leetcode-cn.com/problems/find-the-duplicate-number
25 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
26 | */
27 | public class N287findDuplicate {
28 | public static void main(String[] args) {
29 | int[] nums = {3,1,3,4,2};
30 | System.out.println(new N287findDuplicate().findDuplicate(nums));
31 | }
32 |
33 |
34 |
35 |
36 | public int findDuplicate(int[] nums) {
37 | for (int i = 0; i < nums.length; i++) {
38 | while (nums[i] != nums[nums[i] - 1]) {
39 | change(nums, i, nums[i] - 1);
40 | }
41 | }
42 | return nums[nums.length - 1];
43 | }
44 |
45 | private void change(int[] nums, int pos1, int pos2) {
46 | int tmp = nums[pos1];
47 | nums[pos1] = nums[pos2];
48 | nums[pos2] = tmp;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N448findDisappearedNumbers.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
8 | *
9 | * 找到所有在 [1, n] 范围之间没有出现在数组中的数字。
10 | *
11 | * 您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
12 | *
13 | * 示例:
14 | *
15 | * 输入:
16 | * [4,3,2,7,8,2,3,1]
17 | *
18 | * 输出:
19 | * [5,6]
20 | *
21 | * 来源:力扣(LeetCode)
22 | * 链接:https://leetcode-cn.com/problems/find-all-numbers-disappeared-in-an-array
23 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
24 | */
25 |
26 | public class N448findDisappearedNumbers {
27 | public static void main(String[] args) {
28 | int[] nums = {4,3,2,7,8,2,3,1};
29 | new N448findDisappearedNumbers().findDisappearedNumbers(nums);
30 | }
31 | public List findDisappearedNumbers(int[] nums) {
32 | List list = new ArrayList();
33 | for (int i = 0; i < nums.length ; i++) {
34 | while (nums[i] != nums[nums[i]-1]){
35 | swap(nums,i,nums[i]-1);
36 | }
37 | }
38 |
39 | for (int i = 0; i < nums.length; i++) {
40 | if(nums[i] != i+1){
41 | list.add(i+1);
42 | }
43 | }
44 | return list;
45 |
46 | }
47 |
48 | private void swap(int[] nums, int i, int j){
49 | nums[i] = nums[j] + nums[i];
50 | nums[j] = nums[i] - nums[j];
51 | nums[i] = nums[i] - nums[j];
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N461hammingDistance.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。
5 | *
6 | * 给出两个整数 x 和 y,计算它们之间的汉明距离。
7 | *
8 | * 注意:
9 | * 0 ≤ x, y < 231.
10 | *
11 | * 示例:
12 | *
13 | * 输入: x = 1, y = 4
14 | *
15 | * 输出: 2
16 | *
17 | * 解释:
18 | * 1 (0 0 0 1)
19 | * 4 (0 1 0 0)
20 | * ↑ ↑
21 | *
22 | * 上面的箭头指出了对应二进制位不同的位置。
23 | *
24 | * 来源:力扣(LeetCode)
25 | * 链接:https://leetcode-cn.com/problems/hamming-distance
26 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
27 | */
28 |
29 | public class N461hammingDistance {
30 | public int hammingDistance(int x, int y) {
31 | int cnt = 0;
32 | while (x != 0 || y != 0) {
33 | if ((x & 1) != (y & 1)) {
34 | cnt++;
35 | }
36 | x >>= 1;
37 | y >>= 1;
38 | }
39 | return cnt;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/N739dailyTemperatures.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。
5 | *
6 | * 例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
7 | *
8 | * 提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
9 | *
10 | * 来源:力扣(LeetCode)
11 | * 链接:https://leetcode-cn.com/problems/daily-temperatures
12 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
13 | */
14 | public class N739dailyTemperatures {
15 | public int[] dailyTemperatures(int[] t) {
16 | if (t.length == 0) {
17 | return t;
18 | }
19 | int len = t.length;
20 | int[] res = new int[len];
21 | res[len - 1] = 0;
22 | for (int i = len - 2; i >= 0; i--) {
23 | for (int j = i + 1; j < len; j += res[j]) {
24 | if (t[j] > t[i]) {
25 | res[i] = j - i;
26 | break;
27 | }
28 | if (res[j] == 0) {
29 | res[i] = 0;
30 | break;
31 | }
32 | }
33 | }
34 | return res;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/Palindrome.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/24
6 | * Time: 10:27
7 | * 最长回文串
8 | */
9 |
10 | public class Palindrome {
11 |
12 | public static void main(String[] args) {
13 | String str = "abc1234321ab";
14 | System.out.println(getLongestPalindrome(str,str.length()));
15 | }
16 |
17 |
18 | public static int getLongestPalindrome(String A,int n){
19 | int[][] dp = new int[n][n];
20 | int max = 1;
21 | for (int i = 0; i < n; i++) {
22 | dp[i][i] = 1;
23 | }
24 | char[] a = A.toCharArray();
25 | for (int len = 2;len <= n;len++){ //枚举子串长度
26 | for (int i = 0; i < n-len ; i++) { //枚举子串的起始节点
27 | int j = i + len -1; //枚举子串的终止
28 | if(len == 2 && a[i] == a[j]){
29 | dp[i][j] = len;
30 | max = 2;
31 | continue;
32 | }
33 | if(a[i] == a[j] && dp[i+1][j-1] != 0){
34 | dp[i][j] = len;
35 | max = len;
36 | }
37 | }
38 | }
39 | return max;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/Pow.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | public class Pow {
4 |
5 |
6 | public double myPow(int x,int n){
7 | if(n < 0){
8 |
9 | }
10 | if(n == 0){
11 | return 1;
12 | }
13 | double half = myPow(x,n/2);
14 | if(n % 2 == 0){
15 | return half * half;
16 | }else {
17 | return x*half*half;
18 | }
19 |
20 |
21 | }
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/Reverse.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | /**
4 | * https://blog.csdn.net/ARPOSPF/article/details/81297100
5 | */
6 | public class Reverse {
7 |
8 |
9 | private void reverse(int[] nums){
10 |
11 | if(nums == null || nums.length < 2){
12 | return;
13 | }
14 |
15 |
16 |
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/SmallSum.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | public class SmallSum {
4 |
5 | private static int smallSum(int[] num){
6 | if(num == null || num.length<2){
7 | return 0;
8 | }
9 |
10 | return mergeSort(num,0,num.length-1);
11 |
12 | }
13 |
14 | private static int mergeSort(int[] num, int L, int R) {
15 |
16 | if(L == R){
17 | return 0;
18 | }
19 |
20 | int mid = L+(R-L)>>1;
21 |
22 | return mergeSort(num,L,mid)+mergeSort(num,mid+1,R)+merge(num,L,mid,R);
23 |
24 |
25 |
26 |
27 | }
28 |
29 | private static int merge(int[] num, int l, int mid, int r) {
30 |
31 |
32 | return 0;
33 |
34 | }
35 |
36 |
37 |
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/SmallestKNumber.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Comparator;
5 | import java.util.PriorityQueue;
6 |
7 | public class SmallestKNumber {
8 | public static ArrayList GetLeastNumbers_Solution(int [] input, int k) {
9 | ArrayListlist = new ArrayList<>();
10 | if(input.lengthmaxHeap = new PriorityQueue<>(k, new Comparator() {
15 | @Override
16 | public int compare(Integer o1, Integer o2) {
17 | return o2.compareTo(o1);
18 | }
19 | });
20 |
21 | for (int i = 0; i < input.length; i++) {
22 | if(maxHeap.size()input[i]){
26 | maxHeap.poll();
27 | maxHeap.offer(input[i]);
28 | }
29 | }
30 |
31 | }
32 |
33 | for(Integer num:maxHeap){
34 | list.add(num);
35 | }
36 |
37 | return list;
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/array/YiHuo.java:
--------------------------------------------------------------------------------
1 | package leetcode.array;
2 |
3 | import org.junit.Test;
4 |
5 | public class YiHuo {
6 |
7 | public static void main(String[] args) {
8 | System.out.println((3&1) ==1);
9 | }
10 |
11 | @Test
12 | public void test(){
13 | // System.out.println(hammingWeight(4));
14 | System.out.println(countBits(5));
15 | }
16 |
17 |
18 | public int hammingWeight(int n){
19 | int numberOfOne = 0;
20 | while (n !=0){
21 | numberOfOne++;
22 | n = n&(n-1);
23 |
24 | }
25 | return numberOfOne;
26 | }
27 |
28 |
29 |
30 | public int[] countBits(int num){
31 | int[] res = new int[num+1];
32 | for (int i = 1; i <= num ; i++) {
33 | res[i] = res[i&(i-1)]+1;
34 | }
35 | return res;
36 | }
37 |
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/DoubleList.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | public class DoubleList {
4 | private Node146 head, tail; // 头尾虚节点
5 | private int size; // 链表元素数
6 |
7 | public DoubleList() {
8 | head = new Node146(0, 0);
9 | tail = new Node146(0, 0);
10 | head.next = tail;
11 | tail.prev = head;
12 | size = 0;
13 | }
14 |
15 | // 在链表头部添加节点 x
16 | public void addFirst(Node146 x) {
17 | x.next = head.next;
18 | x.prev = head;
19 | head.next.prev = x;
20 | head.next = x;
21 | size++;
22 | }
23 |
24 | // 删除链表中的 x 节点(x 一定存在)
25 | public void remove(Node146 x) {
26 | x.prev.next = x.next;
27 | x.next.prev = x.prev;
28 | size--;
29 | }
30 |
31 | // 删除链表中最后一个节点,并返回该节点
32 | public Node146 removeLast() {
33 | if (tail.prev == head)
34 | return null;
35 | Node146 last = tail.prev;
36 | remove(last);
37 | return last;
38 | }
39 |
40 | // 返回链表长度
41 | public int size() { return size; }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/ListNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/17
6 | * Time: 16:59
7 | */
8 |
9 | public class ListNode {
10 | public int val;
11 | public ListNode next = null;
12 |
13 | /*
14 | 1->2->5
15 | */
16 |
17 | public ListNode(int val) {
18 | this.val = val;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/N142detectCycle.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | public class N142detectCycle {
4 | public ListNode detectCycle(ListNode head) {
5 |
6 | if (head == null || head.next == null) {
7 | return null;
8 | }
9 | ListNode fast = head.next.next;
10 | ListNode slow = head.next;
11 |
12 | while (fast != null && fast.next != null && fast != slow) {
13 | fast = fast.next.next;
14 | slow = slow.next;
15 | }
16 | if (fast != slow) {
17 | return null;
18 | }
19 | fast = head;
20 | while (fast != slow) {
21 | fast = fast.next;
22 | slow = slow.next;
23 | }
24 |
25 | return fast;
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/N148sortList.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | /*
4 | 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
5 |
6 | 示例 1:
7 |
8 | 输入: 4->2->1->3
9 | 输出: 1->2->3->4
10 |
11 | 示例 2:
12 |
13 | 输入: -1->5->3->4->0
14 | 输出: -1->0->3->4->5
15 |
16 | 来源:力扣(LeetCode)
17 | 链接:https://leetcode-cn.com/problems/sort-list
18 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
19 | */
20 | public class N148sortList {
21 |
22 | public ListNode sortList(ListNode head) {
23 | if (head == null || head.next == null) {
24 | return head;
25 | }
26 | ListNode fast = head.next;
27 | ListNode slow = head;
28 | while (fast != null && fast.next != null) {
29 | fast = fast.next.next;
30 | slow = slow.next;
31 | }
32 | ListNode right = sortList(slow.next);
33 | slow.next = null;
34 | ListNode left = sortList(head);
35 | ListNode res = new ListNode(0);
36 | ListNode tmp = res;
37 | while (left != null && right != null) {
38 | if (left.val < right.val) {
39 | tmp.next = left;
40 | left = left.next;
41 | } else {
42 | tmp.next = right;
43 | right = right.next;
44 | }
45 | tmp = tmp.next;
46 | }
47 | tmp.next = left == null ? right : left;
48 | return res.next;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/N160GetIntersectionNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | public class N160GetIntersectionNode {
4 | public static void main(String[] args) {
5 | ListNode listNode1 = new ListNode(1);
6 | listNode1.next = new ListNode(2);
7 | listNode1.next.next = new ListNode(3);
8 |
9 | ListNode listNode2 = new ListNode(4);
10 | listNode2.next = new ListNode(5);
11 | new N160GetIntersectionNode().getIntersectionNode(listNode1,listNode2);
12 | }
13 | public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
14 | if (headA == null || headB == null) {
15 | return null;
16 | }
17 | ListNode pA = headA;
18 | ListNode pB = headB;
19 | while (pA != pB){
20 | pA = pA == null?headB:pA.next;
21 | pB = pB == null?headA:pB.next;
22 | }
23 | return pA;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/N203removeElements.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | public class N203removeElements {
4 | /*
5 | 删除链表中等于给定值 val 的所有节点。
6 |
7 | 示例:
8 | 输入: 1->2->6->3->4->5->6, val = 6
9 | 输出: 1->2->3->4->5
10 |
11 | head
12 | 1->2->6->3->4->5->6
13 |
14 | res
15 | -1->1->2->6->3->4->5->6
16 |
17 | 1->2->6->3->4->5->6, val = 1
18 |
19 | 2->6->3->4->5->6
20 |
21 | head
22 | 1->2->6->3->4->5->6, val = 6
23 |
24 | head.next =
25 | */
26 |
27 |
28 | /*
29 | 递归写法
30 | */
31 | public ListNode removeElements(ListNode head, int val) {
32 |
33 | if(head == null){
34 | return head;
35 | }
36 | if(head.val == val){
37 | return removeElements(head.next, val);
38 | }else {
39 | head.next = removeElements(head.next, val);
40 | }
41 | return head;
42 |
43 | }
44 |
45 |
46 | public ListNode removeElements1(ListNode head, int val) {
47 | if(head == null){
48 | return head;
49 | }
50 | ListNode res = new ListNode(-1);
51 | ListNode tmp = res;
52 | while (head != null){
53 | if(head.val != val){
54 | res.next = head;
55 | res = res.next;
56 | }
57 | head = head.next;
58 | }
59 | res.next = null;
60 | return tmp.next;
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/N237deleteNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | /**
4 | * 请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
5 | *
6 | * 现有一个链表 -- head = [4,5,1,9],它可以表示为:
7 | *
8 | *
9 | *
10 | * 示例 1:
11 | *
12 | * 输入: head = [4,5,1,9], node = 5
13 | * 输出: [4,1,9]
14 | * 解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
15 | *
16 | * 示例 2:
17 | *
18 | * 输入: head = [4,5,1,9], node = 1
19 | * 输出: [4,5,9]
20 | * 解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
21 | *
22 | * 来源:力扣(LeetCode)
23 | * 链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list
24 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
25 | */
26 | public class N237deleteNode {
27 | public void deleteNode(ListNode node) {
28 |
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/Node146.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | public class Node146 {
4 | public int key, val;
5 | public Node146 next, prev;
6 | public Node146(int k, int v) {
7 | this.key = k;
8 | this.val = v;
9 | }
10 |
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/arraylist/ReorderList.java:
--------------------------------------------------------------------------------
1 | package leetcode.arraylist;
2 |
3 | public class ReorderList {
4 | /**
5 | * Given a singly linked list L: L 0→L 1→…→L n-1→L n,
6 | * reorder it to: L 0→L n →L 1→L n-1→L 2→L n-2→…
7 | *
8 | * You must do this in-place without altering the nodes' values.
9 | *
10 | * For example,
11 | * Given{1,2,3,4}, reorder it to{1,4,2,3}.
12 | */
13 |
14 | public void reorderList(ListNode head) {
15 | if(head == null || head.next ==null){
16 | return;
17 | }
18 | ListNode fast = head;
19 | ListNode slow = head;
20 | while (fast.next!=null&&fast.next.next!=null){
21 | fast = fast.next.next;
22 | slow = slow.next;
23 | }
24 | ListNode next = slow.next;
25 | slow.next = null;
26 | ListNode node = reverse(next);
27 |
28 | while (head!=null||node!=null){
29 |
30 | }
31 |
32 |
33 |
34 | }
35 |
36 | private static ListNode reverse(ListNode listNode){
37 | ListNode pre = null;
38 | ListNode cur = listNode;
39 | ListNode next = null;
40 |
41 | while (cur!=null){
42 | next = cur.next;
43 | cur.next = pre;
44 | pre = cur;
45 | cur = next;
46 | }
47 |
48 | return cur;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/digui/N017letterCombinations.java:
--------------------------------------------------------------------------------
1 | package leetcode.digui;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | public class N017letterCombinations {
7 | String[] telMap = {"_","!@#","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
8 | List res = new ArrayList();
9 | public List letterCombinations(String digits) {
10 | if(digits == null || digits.length() == 0){
11 | return res;
12 | }
13 | process(digits, "", 0);
14 |
15 | return res;
16 |
17 | }
18 |
19 | private void process(String digits, String letter, int index){
20 | if(index == digits.length()){
21 | res.add(letter);
22 | return;
23 | }
24 | String str = telMap[digits.charAt(index)-'0'];
25 | for(int i = 0; i < str.length(); i++){
26 | process(digits,letter+str.charAt(i),index+1);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/digui/N037SolveSudoku.java:
--------------------------------------------------------------------------------
1 | package leetcode.digui;
2 |
3 | /**
4 | * 编写一个程序,通过已填充的空格来解决数独问题。
5 | *
6 | * 一个数独的解法需遵循如下规则:
7 | *
8 | * 数字 1-9 在每一行只能出现一次。
9 | * 数字 1-9 在每一列只能出现一次。
10 | * 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
11 | *
12 | * 空白格用 '.' 表示。
13 | *
14 | * 一个数独。
15 | *
16 | * 答案被标成红色。
17 | *
18 | * Note:
19 | *
20 | * 给定的数独序列只包含数字 1-9 和字符 '.' 。
21 | * 你可以假设给定的数独只有唯一解。
22 | * 给定数独永远是 9x9 形式的。
23 | *
24 | * 来源:力扣(LeetCode)37
25 | * 链接:https://leetcode-cn.com/problems/sudoku-solver
26 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
27 | */
28 |
29 | public class N037SolveSudoku {
30 | public void solveSudoku(char[][] board) {
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/digui/PaiLie.java:
--------------------------------------------------------------------------------
1 | package leetcode.digui;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Stack;
5 |
6 | /**
7 | * created by reedfan on 2019/7/17 0017
8 | */
9 | public class PaiLie {
10 |
11 | public static void main(String[] args) {
12 | int[] nums = {1, 2, 3};
13 | Stack stack = new Stack<>();
14 | ArrayList> result = new ArrayList<>();
15 | generate(0, nums, stack, result);
16 | System.out.println(result);
17 |
18 | }
19 |
20 | private static void generate(int i, int[] nums, Stack stack, ArrayList> result) {
21 | if (i >= nums.length) {
22 | return;
23 | }
24 | stack.push(nums[i]);
25 | result.add(new ArrayList<>(stack));
26 | //放入nums[i]的情况
27 | generate(i + 1, nums, stack, result);
28 | stack.pop();
29 | //不放入nums[i]的情况
30 | generate(i + 1, nums, stack, result);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/digui/Subsets.java:
--------------------------------------------------------------------------------
1 | package leetcode.digui;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * created by reedfan on 2019/5/28 0028
8 | * https://blog.csdn.net/versencoder/article/details/52071930
9 | * https://blog.csdn.net/versencoder/article/details/52072350
10 | */
11 | public class Subsets {
12 |
13 | static List> result=new ArrayList>();
14 |
15 | public static void main(String[] args) {
16 | combine(4,3);
17 |
18 | }
19 | public static List> combine(int n, int k) {
20 | List list=new ArrayList();
21 | backtracking(n,k,1,list);
22 | return result;
23 | }
24 |
25 | public static void backtracking(int n,int k,int start,Listlist){
26 | if(k<0){
27 | return;
28 | }else {
29 | if(k==0){
30 | result.add(new ArrayList<>(list));
31 | }else {
32 |
33 | for (int i = start; i <=n ; i++) {
34 | list.add(i);
35 | backtracking(n,k-1,i+1,list);
36 | list.remove(list.size()-1);
37 |
38 | }
39 |
40 | }
41 |
42 | }
43 |
44 |
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/digui/WordBreaker.java:
--------------------------------------------------------------------------------
1 | package leetcode.digui;
2 |
3 | import java.util.Set;
4 |
5 | /**
6 | * created by reedfan on 2019/5/27 0027
7 | * https://www.programcreek.com/2012/12/leetcode-solution-word-break/
8 | * https://www.cnblogs.com/grandyang/p/4257740.html
9 | *
10 | *
11 | *
12 | */
13 | public class WordBreaker {
14 |
15 |
16 |
17 | public boolean wordBreaker(String str,Set dict){
18 | return wordBreakerHelper(str,dict,0);
19 | }
20 |
21 | public boolean wordBreakerHelper(String str,Set dict,int start){
22 | if(start == str.length()){
23 | return true;
24 | }
25 | for(String a:dict){
26 | int len = a.length();
27 | int end = start+len;
28 | if(end>str.length()){
29 | continue;
30 | }
31 | if(str.substring(start,start+len).equals(a)){
32 | if(wordBreakerHelper(str,dict,start+len)){
33 | return true;
34 | }
35 | }
36 |
37 | }
38 |
39 | return false;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/LeastCoinChange.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | public class LeastCoinChange {
4 |
5 | public static void main(String[] args) {
6 | int[] coins = {1,6,7};
7 | System.out.println(coinChange(coins,30));
8 | }
9 |
10 |
11 | public static int coinChange(int[] coins, int amount) {
12 |
13 | int max = amount + 1;
14 | int[] dp = new int[amount + 1];
15 | for (int i = 0; i < dp.length ; i++) {
16 | dp[i] = max;
17 |
18 | }
19 | dp[0] = 0;
20 | for (int i = 1; i <= amount; i++) {
21 | for (int j = 0; j < coins.length; j++) {
22 | if (coins[j] <= i) {
23 | //其实和跳台阶思路差不多,可以跳上给定的任一级
24 | //因此这里就是选这次到期用哪种钱可以使得当前值最小
25 | dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
26 | }
27 |
28 | }
29 |
30 | }
31 | return dp[amount] > amount ? -1 : dp[amount];
32 |
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/MinCost.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | public class MinCost {
4 |
5 | public int minCost1(String str1,String str2,int ic,int dc,int rc){
6 | if(str1 == null||str2 == null){
7 | return 0;
8 | }
9 | char[] chs1 = str1.toCharArray();
10 | char[] chs2 = str2.toCharArray();
11 | int row = chs1.length+1;
12 | int col = chs2.length+1;
13 | //dp[i][j]表示str1[0...i]编辑成str2[0...j-1]的最小代价
14 | int[][] dp = new int[row][col];
15 | //变成空串当然是删除所有字符
16 | for (int i = 0; i < row; i++) {
17 | dp[i][0] = dc*i;
18 | }
19 | //由空串变成现在的字符串当然是一直加字符
20 | for (int i = 0; i < col; i++) {
21 | dp[0][i] = ic*i;
22 | }
23 | for (int i = 0; i < row ; i++) {
24 | for (int j = 0; j < col; j++) {
25 | if(chs1[i-1] == chs2[j-1]){
26 | dp[i][j] = dp[i-1][j-1];
27 | }else {
28 | dp[i][j] = dp[i-1][j-1]+rc;
29 | }
30 | dp[i][j] = Math.min(dp[i][j],dp[i][j-1]+ic);
31 | dp[i][j] = Math.min(dp[i][j],dp[i-1][j]+dc);
32 |
33 | }
34 |
35 | }
36 | return dp[row-1][col-1];
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/MinimumTotal.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | import org.junit.Test;
4 |
5 | public class MinimumTotal {
6 |
7 | @Test
8 | public void test(){
9 | int[][] triangle = {
10 | {2},
11 | {3,4},
12 | {6,5,7},
13 | {4,1,8,3}};
14 |
15 | System.out.println(minimumTotal(triangle));
16 | }
17 |
18 | /**
19 | * 分析:考虑自底向上的解法简单点,
20 | * 动态转移方程为:
21 | * dp[m][n] = min(dp[m + 1][n], dp[m + 1][n + 1]) + triangle[m][n].
22 | */
23 | public int minimumTotal(int[][] triangle){
24 | if(triangle == null || triangle.length == 0){
25 | return 0;
26 | }
27 | int row = triangle.length;
28 | int[] dp = new int[row];
29 | for (int i = 0; i < row ; i++) {
30 | dp[i] = triangle[row-1][i];
31 | }
32 | for (int i = row - 2; i >= 0; i--) {
33 | for (int j = 0; j <= i ; j++) {
34 | dp[j] = triangle[i][j]+Math.min(dp[j], dp[j+1]);
35 | }
36 |
37 | }
38 | return dp[0];
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/N070ClimbStairs.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | /**
4 | * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
5 | *
6 | * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
7 | *
8 | * 注意:给定 n 是一个正整数。
9 | *
10 | * 示例 1:
11 | *
12 | * 输入: 2
13 | * 输出: 2
14 | * 解释: 有两种方法可以爬到楼顶。
15 | * 1. 1 阶 + 1 阶
16 | * 2. 2 阶
17 | *
18 | * 示例 2:
19 | *
20 | * 输入: 3
21 | * 输出: 3
22 | * 解释: 有三种方法可以爬到楼顶。
23 | * 1. 1 阶 + 1 阶 + 1 阶
24 | * 2. 1 阶 + 2 阶
25 | * 3. 2 阶 + 1 阶
26 | *
27 | * 来源:力扣(LeetCode)70
28 | * 链接:https://leetcode-cn.com/problems/climbing-stairs
29 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
30 | */
31 | public class N070ClimbStairs {
32 | /*
33 | 其实这个可以看做一个斐波那锲数问题。因为每次只能跳一步或者两步。所以a[n]=a[n-1]+a[n-2];
34 | */
35 | public int climbStairs(int n) {
36 | if (n < 1) {
37 | return 0;
38 | }
39 | if (n == 1 || n == 2) {
40 | return n;
41 | }
42 | int a = 1;
43 | int b = 2;
44 | int res = 0;
45 | for (int i = 2; i < n; i++) {
46 | res = a + b;
47 | a = b;
48 | b = res;
49 | }
50 | return res;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/N085MaximalRectangle.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | public class N085MaximalRectangle {
4 |
5 | /**
6 | * 给定一个仅包含 0 和 1 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
7 | *
8 | * 示例:
9 | *
10 | * 输入:
11 | * [
12 | * ["1","0","1","0","0"],
13 | * ["1","0","1","1","1"],
14 | * ["1","1","1","1","1"],
15 | * ["1","0","0","1","0"]
16 | * ]
17 | * 输出: 6
18 | *
19 | * 来源:力扣(LeetCode) 85
20 | * 链接:https://leetcode-cn.com/problems/maximal-rectangle
21 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22 | * @param matrix
23 | * @return
24 | */
25 |
26 | public int maximalRectangle(char[][] matrix) {
27 |
28 |
29 |
30 | return 0;
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/N213Rob.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | /**
4 | * 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
5 | *
6 | * 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
7 | *
8 | * 示例 1:
9 | *
10 | * 输入: [2,3,2]
11 | * 输出: 3
12 | * 解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
13 | *
14 | * 示例 2:
15 | *
16 | * 输入: [1,2,3,1]
17 | * 输出: 4
18 | * 解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
19 | * 偷窃到的最高金额 = 1 + 3 = 4 。
20 | *
21 | * 来源:力扣(LeetCode) 213
22 | * 链接:https://leetcode-cn.com/problems/house-robber-ii
23 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
24 | */
25 |
26 | public class N213Rob {
27 | public int rob(int[] nums) {
28 | if(nums == null || nums.length == 0){
29 | return 0;
30 | }
31 | int len = nums.length;
32 | if(len == 1){
33 | return nums[0];
34 | }
35 | if(len == 2){
36 | return nums[0]>nums[1]?nums[0]:nums[1];
37 | }
38 | return Math.max(help(nums,0,len-2),help(nums,1,len-1));
39 |
40 | }
41 | private int help(int[] nums,int start,int end){
42 | int[] dp = new int[end-start+1];
43 | dp[0] = nums[start];
44 | dp[1] = Math.max(nums[start+1],nums[start]);
45 |
46 | for(int i = start+2;i<=end;i++ ){
47 | dp[i-start] = Math.max(dp[i-start-1],dp[i-start-2]+nums[i]);
48 | }
49 | return dp[end-start];
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/N279numSquares.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | /**
4 | * 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
5 | *
6 | * 示例 1:
7 | *
8 | * 输入: n = 12
9 | * 输出: 3
10 | * 解释: 12 = 4 + 4 + 4.
11 | *
12 | * 示例 2:
13 | *
14 | * 输入: n = 13
15 | * 输出: 2
16 | * 解释: 13 = 4 + 9.
17 | *
18 | * 来源:力扣(LeetCode)
19 | * 链接:https://leetcode-cn.com/problems/perfect-squares
20 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
21 | */
22 | public class N279numSquares {
23 | public static void main(String[] args) {
24 | System.out.println(new N279numSquares().numSquares(24));
25 |
26 | }
27 |
28 | public int numSquares(int n) {
29 | int[] dp = new int[n + 1];
30 | for (int i = 1; i <= n; i++) {
31 | dp[i] = i;
32 | for (int j = 1; j * j <= i; j++) {
33 | dp[i] = dp[i] < (dp[i - j * j] + 1) ? dp[i] : (dp[i - j * j] + 1);
34 |
35 | }
36 | }
37 | return dp[n];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/N377CombinationSum.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | /**
4 | * 给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。
5 | *
6 | * 示例:
7 | *
8 | * nums = [1, 2, 3]
9 | * target = 4
10 | *
11 | * 所有可能的组合为:
12 | * (1, 1, 1, 1)
13 | * (1, 1, 2)
14 | * (1, 2, 1)
15 | * (1, 3)
16 | * (2, 1, 1)
17 | * (2, 2)
18 | * (3, 1)
19 | *
20 | * 请注意,顺序不同的序列被视作不同的组合。
21 | *
22 | * 因此输出为 7。
23 | *
24 | * 进阶:
25 | * 如果给定的数组中含有负数会怎么样?
26 | * 问题会产生什么变化?
27 | * 我们需要在题目中添加什么限制来允许负数的出现?
28 | *
29 | * 来源:力扣(LeetCode)
30 | * 链接:https://leetcode-cn.com/problems/combination-sum-iv
31 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
32 | */
33 | public class N377CombinationSum {
34 | public static void main(String[] args) {
35 | int[] nums = {1, 2, 3};
36 | System.out.println(new N377CombinationSum().combinationSum4(nums, 4));
37 | }
38 |
39 | public int combinationSum4(int[] nums, int target) {
40 | if (nums == null) {
41 | return 0;
42 | }
43 | int[] dp = new int[target + 1];
44 | //dp[0]表示组成0,一个数都不选就可以了,所以dp[0]=1
45 | dp[0] = 1;
46 | for (int i = 1; i <= target; i++) {
47 | for (int num : nums) {
48 | if (i >= num) {
49 | dp[i] += dp[i - num];
50 | }
51 | }
52 |
53 | }
54 |
55 |
56 | return dp[target];
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/N416CanPartition.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | /**
4 | * 给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
5 | *
6 | * 注意:
7 | *
8 | * 每个数组中的元素不会超过 100
9 | * 数组的大小不会超过 200
10 | *
11 | * 示例 1:
12 | *
13 | * 输入: [1, 5, 11, 5]
14 | *
15 | * 输出: true
16 | *
17 | * 解释: 数组可以分割成 [1, 5, 5] 和 [11].
18 | *
19 | *
20 | *
21 | * 示例 2:
22 | *
23 | * 输入: [1, 2, 3, 5]
24 | *
25 | * 输出: false
26 | *
27 | * 解释: 数组不能分割成两个元素和相等的子集.
28 | *
29 | *
30 | * 来源:力扣(LeetCode)416
31 | * 链接:https://leetcode-cn.com/problems/partition-equal-subset-sum
32 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
33 | */
34 | public class N416CanPartition {
35 | //典型的01背包问题。
36 | public boolean canPartition(int[] nums) {
37 | if (nums == null || nums.length == 0) {
38 | return false;
39 | }
40 |
41 | int sum = 0;
42 | for (int num : nums) {
43 | sum += num;
44 | }
45 | if (sum % 2 != 0) {
46 | return false;
47 | }
48 | sum = sum / 2;
49 | boolean[] res = new boolean[sum + 1];
50 | res[0] = true;
51 | //相当于一个01背包问题,用01背包装满sum/2,能不能装满
52 | for (int num : nums) {
53 | for (int i = sum; i >= num; i--) {
54 | res[i] = res[i] || res[i - num];
55 | }
56 | }
57 |
58 | return res[sum];
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/UniquePath.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp;
2 |
3 | /*
4 | https://blog.csdn.net/ZWB626/article/details/84938171
5 | */
6 |
7 | public class UniquePath {
8 |
9 | public int solution(int[][] obstacleGrid) {
10 | int row = obstacleGrid.length; //取得行数
11 | if (row == 0 || obstacleGrid[0][0] == 1) {
12 | return 0;
13 | }
14 | int col = obstacleGrid[0].length;
15 | int[][] steps = new int[row][col];
16 |
17 | steps[0][0] = 1;
18 |
19 | for (int i = 1; i < row; i++) {
20 | if (obstacleGrid[i][0] == 1) {
21 | steps[i][0] = 0;
22 | } else {
23 | steps[i][0] = steps[i - 1][0];
24 | }
25 | }
26 |
27 | for (int i = 1; i < col; i++) {
28 | if (obstacleGrid[0][i] == 1) {
29 | steps[0][i] = 0;
30 |
31 | } else {
32 | steps[0][i] = steps[0][i - 1];
33 |
34 | }
35 | }
36 |
37 | for (int i = 1; i < row; i++) {
38 | for (int j = 1; j < col; j++) {
39 | if(obstacleGrid[i][j] == 1){
40 | steps[i][j] = 0;
41 | }else {
42 | steps[i][j] = steps[i-1][j] + steps[i][j-1];
43 | }
44 |
45 | }
46 |
47 | }
48 | return steps[row-1][col-1];
49 |
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/jingdianwenti/AscentSequence.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp.jingdianwenti;
2 |
3 | public class AscentSequence {
4 | public static void main(String[] args) {
5 | int[] test = {2, 1, 4, 3, 1, 5, 6};
6 | AscentSequence as = new AscentSequence();
7 | System.out.println(as.findLongest(test));
8 | }
9 |
10 | public int findLongest(int[] arr) {
11 | int length = arr.length;
12 | int cur = 0;
13 | int[] tmp = new int[length];
14 | tmp[0] = arr[0];
15 | for (int i = 1; i < length; i++) {
16 | if (arr[i] > tmp[cur]) {
17 | tmp[++cur] = arr[i];
18 | } else {
19 | int pos = findpos(tmp, arr[i], 0, cur);
20 | tmp[pos] = arr[i];
21 | }
22 | }
23 | return cur + 1;
24 | }
25 |
26 | //寻找num在数组中的位置
27 | private int findpos(int[] tmp, int num, int start, int end) {
28 | while (start < end) {
29 | int mid = start + (end - start) / 2;
30 | if (tmp[mid] == num) {
31 | return mid;
32 | }
33 | //因为是要寻找第一个比他大的位置
34 | if (tmp[mid] < num) {
35 | start = mid + 1;
36 | } else {
37 | end = mid;
38 | }
39 | }
40 | return start;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/knapsack/KnapsackDigui.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp.knapsack;
2 |
3 | public class KnapsackDigui {
4 | public static void main(String[] args) {
5 | int c=5;
6 | int v[]={6,10,12},w[]={1,2,3};
7 | int res= knapsack(c,w,v);
8 | System.out.println(res);
9 | }
10 | public static int knapsack(int capacity, int[] weights, int[] values) {
11 | int n = weights.length;
12 | //递归的套路,加一个index索引,控制递归到了哪一层
13 | return bestValue(capacity,n-1,weights,values);
14 | }
15 |
16 | private static int bestValue(int capacity, int index, int[] weights, int[] values){
17 | //递归的第一步:终止条件,没有商品了或者背包没容量了就终止
18 | if(index <= 0 || capacity<= 0){
19 | return 0;
20 | }
21 | //不放的情况
22 | int res = bestValue(capacity,index-1,weights,values);
23 | //放的情况,需要剩余满足容量>=weights[index]
24 | if(capacity >= weights[index]){
25 | //放的情况为bestValue(capacity - weights[index],index-1,weights,values)。也就是index放进去。其他的容量放
26 | //前面index-1
27 | res = Math.max(res,values[index]+bestValue(capacity - weights[index],index-1,weights,values));
28 | }
29 | return res;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/knapsack/KnapsackErweidp.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp.knapsack;
2 |
3 | public class KnapsackErweidp {
4 | public static void main(String[] args) {
5 | int c=5;
6 | int v[]={6,10,12},w[]={1,2,3};
7 | int res= knapsack(c,w,v);
8 | System.out.println(res);
9 | }
10 | public static int knapsack(int capacity, int[] weights, int[] values) {
11 | assert (weights.length == weights.length);
12 | int len = weights.length;
13 | if(len == 0){
14 | return 0;
15 | }
16 | //dp表示i个物品放进容量为c的背包的效益
17 | int[][] dp = new int[len][capacity+1];
18 | //初始化第一列,第一列表示背包容量为0的时候,所以第一列的值都为0
19 | for (int i = 0; i < len ; i++) {
20 | dp[i][0] = 0;
21 | }
22 | //初始化第一行。第一行表示只有一个物品。所以只要capacity >= weights[0],就初始化为values[0]
23 | for (int i = 1; i <= capacity ; i++) {
24 | dp[0][i] = capacity >= weights[0]?values[0]:0;
25 | }
26 | for (int i = 1; i < len ; i++) {
27 | for (int j = 1; j <= capacity ; j++) {
28 | //第i个物品放不时的结果,和只有i-1个物品的结果一样
29 | dp[i][j] = dp[i-1][j];
30 | //第i个物品能放下
31 | if(j >= weights[i]){
32 | //比较放和不放哪种能产生更高的价值
33 | dp[i][j] = Math.max(dp[i][j],values[i]+dp[i-1][j-weights[i]]);
34 | }
35 | }
36 | }
37 | return dp[len-1][capacity];
38 |
39 | }
40 |
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/knapsack/KnapsackErweidpYasuo.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp.knapsack;
2 |
3 | public class KnapsackErweidpYasuo {
4 | public static void main(String[] args) {
5 | int c=5;
6 | int v[]={6,10,12},w[]={1,2,3};
7 | int res= knapsack(c,w,v);
8 | System.out.println(res);
9 | }
10 | public static int knapsack(int capacity, int[] weights, int[] values) {
11 | assert (weights.length == weights.length);
12 | int len = weights.length;
13 | if(len == 0){
14 | return 0;
15 | }
16 | //dp表示i个物品放进容量为capacity的背包的效益
17 | int[] dp = new int[capacity+1];
18 |
19 | for (int i = 0; i < len ; i++) {
20 | //注意一定为倒序,j < weights[i]的话,表示放不下了。那么可以终止循环。这是动态规划中
21 | //一个常用的做法。减枝
22 | for (int j = capacity; j >= weights[i]; j--) {
23 | dp[j] = Math.max(dp[j],values[i]+dp[j-weights[i]]);
24 |
25 | }
26 | }
27 | return dp[capacity];
28 |
29 | }
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/dp/knapsack/WanQuanBeiBao.java:
--------------------------------------------------------------------------------
1 | package leetcode.dp.knapsack;
2 |
3 | public class WanQuanBeiBao {
4 | public static void main(String[] args) {
5 | int c = 4;
6 | int v[] = {1, 1, 1}, w[] = {1, 2, 3};
7 | int res = knapsack(c, w, v);
8 | System.out.println(res);
9 | }
10 |
11 | public static int knapsack(int capacity, int[] weights, int[] values) {
12 | assert (weights.length == weights.length);
13 | int len = weights.length;
14 | if (len == 0) {
15 | return 0;
16 | }
17 | //dp表示i个物品放进容量为capacity的背包的效益
18 | int[] dp = new int[capacity + 1];
19 | for (int i = 0; i < len; i++) {
20 | //必须满足容量>=weights[i]才能放入
21 | for (int j = weights[i]; j <= capacity; j++) {
22 | dp[j] = Math.max(dp[j], values[i] + dp[j - weights[i]]);
23 | }
24 | }
25 | return dp[capacity];
26 |
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/erfen/N050myPow.java:
--------------------------------------------------------------------------------
1 | package leetcode.erfen;
2 |
3 | /**
4 | * 实现 pow(x, n) ,即计算 x 的 n 次幂函数。
5 | *
6 | * 示例 1:
7 | *
8 | * 输入: 2.00000, 10
9 | * 输出: 1024.00000
10 | *
11 | * 示例 2:
12 | *
13 | * 输入: 2.10000, 3
14 | * 输出: 9.26100
15 | *
16 | * 示例 3:
17 | *
18 | * 输入: 2.00000, -2
19 | * 输出: 0.25000
20 | * 解释: 2-2 = 1/22 = 1/4 = 0.25
21 | *
22 | * 来源:力扣(LeetCode)
23 | * 链接:https://leetcode-cn.com/problems/powx-n
24 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
25 | */
26 | public class N050myPow {
27 | public double myPow(double x, int n) {
28 | if (n == 0) {
29 | return 1;
30 | }
31 | if (n == 1) {
32 | return x;
33 | }
34 | if (n == -1) {
35 | return 1 / x;
36 | }
37 | double half = myPow(x, n / 2);
38 | double rest = myPow(x, n % 2);
39 | return half * half * rest;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/erfen/N069MySqrt.java:
--------------------------------------------------------------------------------
1 | package leetcode.erfen;
2 |
3 | /**
4 | * 实现 int sqrt(int x) 函数。
5 | *
6 | * 计算并返回 x 的平方根,其中 x 是非负整数。
7 | *
8 | * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
9 | *
10 | * 示例 1:
11 | *
12 | * 输入: 4
13 | * 输出: 2
14 | *
15 | * 示例 2:
16 | *
17 | * 输入: 8
18 | * 输出: 2
19 | * 说明: 8 的平方根是 2.82842...,
20 | * 由于返回类型是整数,小数部分将被舍去。
21 | *
22 | * 来源:力扣(LeetCode) 69
23 | * 链接:https://leetcode-cn.com/problems/sqrtx
24 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
25 | */
26 |
27 | public class N069MySqrt {
28 | public static void main(String[] args) {
29 | System.out.println(new N069MySqrt().mySqrt(2147395599));
30 | }
31 |
32 | /*
33 | 本题的解法类似于数学中的夹逼定理。从两边向中间以二分的方式进行夹击。
34 | 里面还有一些小技巧。为了防止数据越界。比如 a很大。我们要比较a*a和b的大小。因为a*a可能超过Integer.MAX_VALUE。
35 | 所以可以比较a和b/a的大小。
36 |
37 | */
38 | public int mySqrt(int x) {
39 | if (x == 1 || x == 0) {
40 | return x;
41 | }
42 | int start = 1;
43 | int end = x / 2 + 1;
44 | int mid = 0;
45 | while (start <= end) {
46 | mid = start + (end - start) / 2;
47 | //防止越界
48 | if (mid <= x / mid && (mid + 1) > x / (mid + 1)) {
49 | return mid;
50 | }
51 | if (mid > x / mid) {
52 | end = mid - 1;
53 | } else {
54 | start = mid + 1;
55 | }
56 | }
57 | return mid;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/erfen/N153findMin.java:
--------------------------------------------------------------------------------
1 | package leetcode.erfen;
2 |
3 | /**
4 | * 假设按照升序排序的数组在预先未知的某个点上进行了旋转。
5 |
6 | ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
7 |
8 | 请找出其中最小的元素。
9 |
10 | 你可以假设数组中不存在重复元素。
11 |
12 | 示例 1:
13 |
14 | 输入: [3,4,5,1,2]
15 | 输出: 1
16 |
17 | 示例 2:
18 |
19 | 输入: [4,5,6,7,0,1,2]
20 | 输出: 0
21 |
22 | 来源:力扣(LeetCode)
23 | 链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array
24 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
25 | */
26 |
27 |
28 | /**
29 | * 0 1 2 3 4 5 6 7
30 | *
31 | * 7 0 1 2 3 4 5 6
32 | *
33 | * 1 2 3 4 5 6 7 0 nums[mid]>nums[end]这种情况下。说明最小值在中点的右边
34 | *
35 | *
36 | *
37 | */
38 |
39 |
40 | public class N153findMin {
41 | public static void main(String[] args) {
42 | int[] nums = {4,5,6,7,0,1,2};
43 | System.out.println(new N153findMin().findMin(nums));
44 | }
45 |
46 |
47 |
48 |
49 |
50 | public int findMin(int[] nums) {
51 |
52 | if(nums.length == 1){
53 | return nums[0];
54 | }
55 |
56 | return process(nums,0,nums.length-1);
57 | }
58 |
59 | private int process(int[] nums, int start, int end){
60 | int mid = 0;
61 | while (start < end){
62 | mid = start + (end -start) /2;
63 | //前半部分有序,一定在后半部分
64 | if(nums[mid] > nums[end]){
65 | start = mid + 1;
66 | }else {
67 | end = mid;
68 | }
69 | }
70 | return nums[start];
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/erfen/N154findMin.java:
--------------------------------------------------------------------------------
1 | package leetcode.erfen;
2 |
3 | /**
4 | * 假设按照升序排序的数组在预先未知的某个点上进行了旋转。
5 |
6 | ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
7 |
8 | 请找出其中最小的元素。
9 |
10 | 注意数组中可能存在重复的元素。
11 |
12 | 示例 1:
13 |
14 | 输入: [1,3,5]
15 | 输出: 1
16 |
17 | 示例 2:
18 |
19 | 输入: [2,2,2,0,1]
20 | 输出: 0
21 |
22 | 说明:
23 |
24 | 这道题是 寻找旋转排序数组中的最小值 的延伸题目。
25 | 允许重复会影响算法的时间复杂度吗?会如何影响,为什么?
26 |
27 | 来源:力扣(LeetCode)
28 | 链接:https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii
29 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
30 | */
31 | public class N154findMin {
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | public static void main(String[] args) {
40 | int[] nums = {2,2,2,0,1,2};
41 | System.out.println(new N154findMin().findMin1(nums));
42 | }
43 | public int findMin1(int[] nums) {
44 |
45 | if(nums.length == 1){
46 | return nums[0];
47 | }
48 |
49 | return process(nums,0,nums.length-1);
50 | }
51 |
52 | private int process(int[] nums, int start, int end){
53 | int mid = 0;
54 | while (start < end){
55 | mid = start + (end -start) /2;
56 | if(nums[mid] == nums[end]){
57 | end--;
58 | continue;
59 |
60 | }
61 | //前半部分有序,一定在后半部分
62 | if(nums[mid] > nums[end]){
63 | start = mid + 1;
64 | }else {
65 | end = mid;
66 | }
67 | }
68 | return nums[start];
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/gredy/N053MaxSubArray.java:
--------------------------------------------------------------------------------
1 | package leetcode.gredy;
2 |
3 | /**
4 | * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
5 | *
6 | * 示例:
7 | *
8 | * 输入: [-2,1,-3,4,-1,2,1,-5,4],
9 | * 输出: 6
10 | * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
11 | *
12 | * 进阶:
13 | *
14 | * 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
15 | *
16 | * 来源:力扣(LeetCode)
17 | * 链接:https://leetcode-cn.com/problems/maximum-subarray
18 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
19 | */
20 |
21 | public class N053MaxSubArray {
22 |
23 | /*
24 | 当记录到第n个数的时候 ,用一个变量sum记录连续序列的和。那么如果sum<=0的话。
25 | 表明sum+nums[n]将会小于nums[n]。因此。如果我么要找最大的序列和,前面的sum对我们是没有帮助的。
26 | 我们应该将其舍弃。即sum = nums[n]。如果sum > 0的话。sum+nums[n]将会大于nums[n]。
27 | 因此sum = sum+nums[n]。
28 | 用res表示最大子序列和。每次更新完sum的值,看看sum是否比res大。如果比res大,更新res为num的值。
29 | */
30 |
31 |
32 | public int maxSubArray(int[] nums) {
33 | if (nums == null || nums.length == 0) {
34 | return 0;
35 | }
36 | int res = nums[0];
37 | int sum = nums[0];
38 | for (int i = 1; i < nums.length; i++) {
39 | if (sum <= 0) {
40 | sum = nums[i];
41 | } else {
42 | sum += nums[i];
43 | }
44 | res = res > sum ? res : sum;
45 | }
46 |
47 | return res;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/gredy/N121maxProfit.java:
--------------------------------------------------------------------------------
1 | package leetcode.gredy;
2 |
3 | /**
4 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
5 |
6 | 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
7 |
8 | 注意你不能在买入股票前卖出股票。
9 |
10 | 示例 1:
11 |
12 | 输入: [7,1,5,3,6,4]
13 | 输出: 5
14 | 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
15 | 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
16 |
17 | 示例 2:
18 |
19 | 输入: [7,6,4,3,1]
20 | 输出: 0
21 | 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
22 |
23 | 来源:力扣(LeetCode)
24 | 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
25 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
26 | */
27 | public class N121maxProfit {
28 | public int maxProfit(int[] prices) {
29 | if(prices == null || prices.length == 0){
30 | return 0;
31 | }
32 | int minPrice = prices[0];
33 | int maxProfit = 0;
34 | for(int i = 1; i < prices.length; i++){
35 | maxProfit = maxProfit > (prices[i] - minPrice) ? maxProfit : (prices[i] - minPrice);
36 | minPrice = minPrice < prices[i] ? minPrice : prices[i];
37 | }
38 | return maxProfit;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/gredy/N122maxProfit.java:
--------------------------------------------------------------------------------
1 | package leetcode.gredy;
2 |
3 | /**
4 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
5 |
6 | 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
7 |
8 | 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
9 |
10 | 示例 1:
11 |
12 | 输入: [7,1,5,3,6,4]
13 | 输出: 7
14 | 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
15 | 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
16 |
17 | 示例 2:
18 |
19 | 输入: [1,2,3,4,5]
20 | 输出: 4
21 | 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
22 | 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
23 | 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
24 |
25 | 示例 3:
26 |
27 | 输入: [7,6,4,3,1]
28 | 输出: 0
29 | 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
30 |
31 | 来源:力扣(LeetCode)
32 | 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
33 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
34 | */
35 | public class N122maxProfit {
36 |
37 | /*
38 | 只要后面的数比前面的一个数大,就可以将其加入结果。
39 | */
40 | public int maxProfit(int[] prices) {
41 | if(prices == null || prices.length < 2){
42 | return 0;
43 | }
44 | int maxProfit = 0;
45 | for(int i = 1; i < prices.length; i++){
46 | if(prices[i] > prices[i-1]){
47 | maxProfit += (prices[i] - prices[i-1]);
48 | }
49 | }
50 | return maxProfit;
51 |
52 | }
53 |
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/huadongchuangkou/IsAnagram.java:
--------------------------------------------------------------------------------
1 | package leetcode.huadongchuangkou;
2 |
3 | public class IsAnagram {
4 | public boolean isAnagram(String s, String p) {
5 | if (s == null || s.length() == 0 || p == null || p.length() == 0 || s.length() < p.length()) {
6 | return false;
7 | }
8 | int len = p.length();
9 | int[] tmp = new int[26];
10 | int[] windonw = new int[26];
11 |
12 | for (int i = 0; i < len; i++) {
13 | tmp[p.charAt(i) - 'a']++; // 记录p串有哪些字符
14 | windonw[s.charAt(i) - 'a']++;
15 | }
16 | int l = 0;
17 | int r = len;
18 | while (r < s.length()) {
19 | if (cmp(windonw, tmp)) {
20 | return true;
21 | }
22 | windonw[s.charAt(r++) - 'a']++;
23 | windonw[s.charAt(l++) - 'a']--;
24 |
25 | }
26 | if (cmp(windonw, tmp)) { //末尾的那个
27 | return true;
28 | }
29 | return false;
30 |
31 | }
32 |
33 |
34 | private boolean cmp(int[] array1, int[] array2) {
35 | for (int i = 0; i < array1.length; i++) {
36 | if (array1[i] != array2[i]) {
37 | return false;
38 | }
39 |
40 | }
41 | return true;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/huadongchuangkou/N209minSubArrayLen.java:
--------------------------------------------------------------------------------
1 | package leetcode.huadongchuangkou;
2 |
3 | /**
4 | * 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
5 | *
6 | * 示例:
7 | *
8 | * 输入: s = 7, nums = [2,3,1,2,4,3]
9 | * 输出: 2
10 | * 解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
11 | *
12 | * 来源:力扣(LeetCode)
13 | * 链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
14 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
15 | */
16 | public class N209minSubArrayLen {
17 | public static void main(String[] args) {
18 | int[] nums = {2, 3, 1, 2, 4, 3};
19 | int res = new N209minSubArrayLen().minSubArrayLen(7, nums);
20 | System.out.println(res);
21 | }
22 |
23 | public int minSubArrayLen(int s, int[] nums) {
24 | if (nums == null || nums.length == 0) {
25 | return 0;
26 | }
27 | int minLen = Integer.MAX_VALUE;
28 | int left = 0;
29 | int right = 1;
30 | int sum = nums[0];
31 | while (left < nums.length) {
32 | if (sum >= s) {
33 | minLen = minLen < (right - left) ? minLen : (right - left);
34 | sum -= nums[left];
35 | left++;
36 | } else {
37 | if (right < nums.length) {
38 | sum += nums[right++];
39 | } else {
40 | return minLen == Integer.MAX_VALUE ? 0 : minLen;
41 | }
42 | }
43 | }
44 | return minLen == Integer.MAX_VALUE ? 0 : minLen;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/math/N292canWinNim.java:
--------------------------------------------------------------------------------
1 | package leetcode.math;
2 |
3 | /**
4 | * 你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
5 | *
6 | * 你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
7 | *
8 | * 示例:
9 | *
10 | * 输入: 4
11 | * 输出: false
12 | * 解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
13 | * 因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
14 | *
15 | * 来源:力扣(LeetCode)
16 | * 链接:https://leetcode-cn.com/problems/nim-game
17 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
18 | */
19 | public class N292canWinNim {
20 | public boolean canWinNim(int n) {
21 | if (n % 4 == 0) {
22 | return false;
23 | }
24 | return true;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/math/N470Rand.java:
--------------------------------------------------------------------------------
1 | package leetcode.math;
2 |
3 | import java.util.Random;
4 |
5 | public class N470Rand {
6 | public int rand10() {
7 | while (true){
8 | int num = (rand7()-1)*7 + rand7()-1;
9 | if(num < 40){
10 | return num%10+1;
11 | }
12 | }
13 |
14 | }
15 |
16 | private int rand7(){
17 | return new Random().nextInt(7);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/N009IsPalindrome.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | /**
4 | * 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
5 | *
6 | * 示例 1:
7 | *
8 | * 输入: 121
9 | * 输出: true
10 | *
11 | * 示例 2:
12 | *
13 | * 输入: -121
14 | * 输出: false
15 | * 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
16 | *
17 | * 示例 3:
18 | *
19 | * 输入: 10
20 | * 输出: false
21 | * 解释: 从右向左读, 为 01 。因此它不是一个回文数。
22 | *
23 | * 来源:力扣(LeetCode) 9
24 | * 链接:https://leetcode-cn.com/problems/palindrome-number
25 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
26 | */
27 | public class N009IsPalindrome {
28 | public static void main(String[] args) {
29 | new N009IsPalindrome().isPalindrome(1001);
30 | }
31 |
32 | public boolean isPalindrome(int x) {
33 | if (x < 0) {
34 | return false;
35 | }
36 | int help = 1;
37 | int tmp = x;
38 | while (tmp >= 10) {
39 | help *= 10;
40 | tmp /= 10;
41 | }
42 | while (x != 0) {
43 | if (x % 10 != x / help) {
44 | return false;
45 | }
46 | x = x % help / 10;
47 | help /= 100;
48 | }
49 | return true;
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/N088Merge.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | /**
4 | * 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
5 | *
6 | * 说明:
7 | *
8 | * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
9 | * 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
10 | *
11 | * 示例:
12 | *
13 | * 输入:
14 | * nums1 = [1,2,3,0,0,0], m = 3
15 | * nums2 = [2,5,6], n = 3
16 | *
17 | * 输出: [1,2,2,3,5,6]
18 | *
19 | * 来源:力扣(LeetCode)
20 | * 链接:https://leetcode-cn.com/problems/merge-sorted-array
21 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22 | */
23 |
24 | public class N088Merge {
25 | public void merge(int[] nums1, int m, int[] nums2, int n) {
26 | int pos = m + n - 1;
27 | int s1 = m - 1;
28 | int s2 = n - 1;
29 | while (s1 >= 0 && s2 >= 0) {
30 | if (nums1[s1] >= nums2[s2]) {
31 | nums1[pos--] = nums1[s1--];
32 | } else {
33 | nums1[pos--] = nums2[s2--];
34 | }
35 | }
36 | while (s1 >= 0) {
37 | nums1[pos--] = nums1[s1--];
38 | }
39 | while (s2 >= 0) {
40 | nums1[pos--] = nums2[s2--];
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/N123MaxProfit.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | /**
4 | * 给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
5 | *
6 | * 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
7 | *
8 | * 注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
9 | *
10 | * 示例 1:
11 | *
12 | * 输入: [3,3,5,0,0,3,1,4]
13 | * 输出: 6
14 | * 解释: 在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
15 | * 随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
16 | *
17 | * 示例 2:
18 | *
19 | * 输入: [1,2,3,4,5]
20 | * 输出: 4
21 | * 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
22 | * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
23 | * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
24 | *
25 | * 示例 3:
26 | *
27 | * 输入: [7,6,4,3,1]
28 | * 输出: 0
29 | * 解释: 在这个情况下, 没有交易完成, 所以最大利润为 0。
30 | *
31 | * 来源:力扣(LeetCode)
32 | * 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iii
33 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
34 | */
35 |
36 | public class N123MaxProfit {
37 | public static void main(String[] args) {
38 |
39 |
40 | }
41 | public int maxProfit(int[] prices) {
42 |
43 |
44 | return 0;
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/N344reverseString.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | /**
4 | * 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
5 | *
6 | * 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
7 | *
8 | * 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
9 | *
10 | *
11 | *
12 | * 示例 1:
13 | *
14 | * 输入:["h","e","l","l","o"]
15 | * 输出:["o","l","l","e","h"]
16 | *
17 | * 示例 2:
18 | *
19 | * 输入:["H","a","n","n","a","h"]
20 | * 输出:["h","a","n","n","a","H"]
21 | *
22 | * 来源:力扣(LeetCode)
23 | * 链接:https://leetcode-cn.com/problems/reverse-string
24 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
25 | */
26 | public class N344reverseString {
27 | public void reverseString(char[] s) {
28 | if (s == null || s.length < 2) {
29 | return;
30 | }
31 | int left = -1;
32 | int right = s.length;
33 | while (++left < --right) {
34 | char c = s[left];
35 | s[left] = s[right];
36 | s[right] = c;
37 | }
38 |
39 | return;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/N524FindLongestWord.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * 给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。
7 | * 如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
8 | *
9 | * 示例 1:
10 | *
11 | * 输入:
12 | * s = "abpcplea", d = ["ale","apple","monkey","plea"]
13 | *
14 | * 输出:
15 | * "apple"
16 | *
17 | * 示例 2:
18 | *
19 | * 输入:
20 | * s = "abpcplea", d = ["a","b","c"]
21 | *
22 | * 输出:
23 | * "a"
24 | *
25 | *
26 | * 来源:力扣(LeetCode)524
27 | * 链接:https://leetcode-cn.com/problems/longest-word-in-dictionary-through-deleting
28 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
29 | */
30 | public class N524FindLongestWord {
31 | public String findLongestWord(String s, List d) {
32 | String result = "";
33 | for (String str : d) {
34 | if(str.length()0)){
35 | continue;
36 | }
37 | if(isSub(s,str)){
38 | result = str;
39 | }
40 | }
41 |
42 | return result;
43 | }
44 | private boolean isSub(String source,String target){
45 | int i1 = 0;
46 | int i2 = 0;
47 | for(;i1
6 | * 示例 1:
7 | *
8 | * 输入: "aba"
9 | * 输出: True
10 | *
11 | * 示例 2:
12 | *
13 | * 输入: "abca"
14 | * 输出: True
15 | * 解释: 你可以删除c字符。
16 | *
17 | * 来源:力扣(LeetCode) 680
18 | * 链接:https://leetcode-cn.com/problems/valid-palindrome-ii
19 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
20 | */
21 |
22 | public class N680ValidPalindrom {
23 | public boolean validPalindrome(String s) {
24 | if (s == null || s.length() == 0) {
25 | return false;
26 | }
27 | int len = s.length();
28 | int start = 0;
29 | int end = len-1;
30 | for (; start < end; start++, end--) {
31 | if (s.charAt(start) != s.charAt(end)) {
32 | return isPalindrome(s, start + 1, end) || isPalindrome(s, start, end - 1);
33 | }
34 |
35 | }
36 | return true;
37 | }
38 |
39 | private boolean isPalindrome(String str, int left, int right) {
40 | while (left < right) {
41 | if (str.charAt(left++) != str.charAt(right--)) {
42 | return false;
43 | }
44 | }
45 | return true;
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/N763PartitionLabels.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
8 | *
9 | * 示例 1:
10 | *
11 | * 输入: S = "ababcbacadefegdehijhklij"
12 | * 输出: [9,7,8]
13 | * 解释:
14 | * 划分结果为 "ababcbaca", "defegde", "hijhklij"。
15 | * 每个字母最多出现在一个片段中。
16 | * 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
17 | *
18 | * 来源:力扣(LeetCode)
19 | * 链接:https://leetcode-cn.com/problems/partition-labels
20 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
21 | */
22 |
23 | public class N763PartitionLabels {
24 | public List partitionLabels(String S) {
25 | List list = new ArrayList<>();
26 | if(S.length() == 1){
27 | list.add(1);
28 | return list;
29 |
30 | }
31 |
32 | int[] lastindex = new int[26];
33 |
34 | for (int i = 0; i < S.length() ; i++) {
35 | lastindex[S.charAt(i)-'a'] = i;
36 | }
37 |
38 | int index = 0;
39 | int maxPos = lastindex[S.charAt(0)-'a'];
40 |
41 |
42 | for (int i = 1; i < S.length() ; i++) {
43 | if(maxPos >= lastindex[S.charAt(i)-'a']){
44 |
45 | }else {
46 |
47 | }
48 | }
49 |
50 | return null;
51 |
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/shuangzhizhen/ReconstructQueue.java:
--------------------------------------------------------------------------------
1 | package leetcode.shuangzhizhen;
2 |
3 | public class ReconstructQueue {
4 | /**
5 | * 假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。
6 | * 编写一个算法来重建这个队列。
7 | *
8 | * 注意:
9 | * 总人数少于1100人。
10 | *
11 | * 示例
12 | *
13 | * 输入:
14 | * [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
15 | *
16 | * 输出:
17 | * [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
18 | *
19 | * 来源:力扣(LeetCode)
20 | * 链接:https://leetcode-cn.com/problems/queue-reconstruction-by-height
21 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22 | */
23 |
24 | public int[][] reconstructQueue(int[][] people) {
25 |
26 |
27 |
28 |
29 | return null;
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/sousuo/N200NumIslands.java:
--------------------------------------------------------------------------------
1 | package leetcode.sousuo;
2 |
3 | /**
4 | * 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
5 | *
6 | * 示例 1:
7 | *
8 | * 输入:
9 | * 11110
10 | * 11010
11 | * 11000
12 | * 00000
13 | *
14 | * 输出: 1
15 | *
16 | * 示例 2:
17 | *
18 | * 输入:
19 | * 11000
20 | * 11000
21 | * 00100
22 | * 00011
23 | *
24 | * 输出: 3
25 | *
26 | * 来源:力扣(LeetCode)
27 | * 链接:https://leetcode-cn.com/problems/number-of-islands
28 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
29 | */
30 | public class N200NumIslands {
31 | public int numIslands(char[][] grid) {
32 | if (grid == null || grid.length == 0 || grid[0].length == 0) {
33 | return 0;
34 | }
35 | int row = grid.length;
36 | int col = grid[0].length;
37 | int num = 0;
38 | for (int i = 0; i < row; i++) {
39 | for (int j = 0; j < col; j++) {
40 | if (grid[i][j] == '1') {
41 | num++;
42 | search(grid, i, j, row, col);
43 | }
44 | }
45 | }
46 | return num;
47 | }
48 | private void search(char[][] grid, int x, int y, int row, int col) {
49 | if (x < 0 || x >= row || y < 0 || y >= col || grid[x][y] != '1') {
50 | return;
51 | }
52 | grid[x][y] = '2';
53 | search(grid, x - 1, y, row, col);
54 | search(grid, x + 1, y, row, col);
55 | search(grid, x, y - 1, row, col);
56 | search(grid, x, y + 1, row, col);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/stack/KuoHaoPiPei.java:
--------------------------------------------------------------------------------
1 | package leetcode.stack;
2 |
3 | import java.util.Stack;
4 |
5 | public class KuoHaoPiPei {
6 | public static void main(String[] args) {
7 | String test = "{1+(2+3)+[(1+3)+(4*5)]}";
8 | System.out.println(isValid(test));
9 |
10 | }
11 | public static boolean isValid(String expression) {
12 | char[] chs = expression.toCharArray();
13 | Stack stack = new Stack<>();
14 | for (int i = 0; i < chs.length; i++) {
15 | if (chs[i] == '{' || chs[i] == '[' || chs[i] == '(') {
16 | stack.add(chs[i]);
17 | }
18 | if (chs[i] == '}' || chs[i] == ']' || chs[i] == ')') {
19 | char match = chs[i] == '}'?'{':(chs[i]==']'?'[':'(');
20 | if(stack.isEmpty()||!stack.pop().equals(match)){
21 | return false;
22 | }
23 | }
24 | }
25 | return stack.isEmpty();
26 |
27 | }
28 |
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/stack/N155MinStack.java:
--------------------------------------------------------------------------------
1 | package leetcode.stack;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。
7 | *
8 | * push(x) -- 将元素 x 推入栈中。
9 | * pop() -- 删除栈顶的元素。
10 | * top() -- 获取栈顶元素。
11 | * getMin() -- 检索栈中的最小元素。
12 | *
13 | * 示例:
14 | *
15 | * MinStack minStack = new MinStack();
16 | * minStack.push(-2);
17 | * minStack.push(0);
18 | * minStack.push(-3);
19 | * minStack.getMin(); --> 返回 -3.
20 | * minStack.pop();
21 | * minStack.top(); --> 返回 0.
22 | * minStack.getMin(); --> 返回 -2.
23 | *
24 | * 来源:力扣(LeetCode)
25 | * 链接:https://leetcode-cn.com/problems/min-stack
26 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
27 | */
28 | public class N155MinStack {
29 |
30 | Stack stack = new Stack<>();
31 | Stack minStack = new Stack<>();
32 |
33 | public void push(int x) {
34 | stack.push(x);
35 | if (!minStack.empty() && x > minStack.peek()) {
36 | minStack.push(minStack.peek());
37 | } else {
38 | minStack.push(x);
39 | }
40 |
41 |
42 | }
43 |
44 | public void pop() {
45 | stack.pop();
46 | minStack.pop();
47 |
48 | }
49 |
50 | public int top() {
51 | return stack.peek();
52 | }
53 |
54 | public int getMin() {
55 | return minStack.peek();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/stack/StackPiPei.java:
--------------------------------------------------------------------------------
1 | package leetcode.stack;
2 |
3 | import java.util.Stack;
4 | /**
5 | * Author 范群松.
6 | * Date:2018/8/18
7 | * Time: 16:15
8 | * 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
9 | * 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,
10 | * 序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
11 | * (注意:这两个序列的长度是相等的)
12 | */
13 | public class StackPiPei {
14 | public static boolean IsPopOrder(int [] pushA,int [] popA) {
15 | if(pushA==null||popA==null||pushA.length==0||popA.length==0||pushA.length!=popA.length){
16 | return false;
17 | }
18 | Stack stack = new Stack<>();
19 | int index = 0;
20 | for (int i = 0; i
6 | * 如果不存在最后一个单词,请返回 0 。
7 | *
8 | * 说明:一个单词是指由字母组成,但不包含任何空格的字符串。
9 | *
10 | * 示例:
11 | *
12 | * 输入: "Hello World"
13 | * 输出: 5
14 | *
15 | * 来源:力扣(LeetCode)
16 | * 链接:https://leetcode-cn.com/problems/length-of-last-word
17 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
18 | */
19 | public class N058LengthOfLastWord {
20 | public int lengthOfLastWord(String s) {
21 | int count = 0;
22 | int index = s.length() - 1;
23 | //过滤空格
24 | while (index >= 0 && s.charAt(index) == ' ') {
25 | index--;
26 | }
27 | //计算最后一个单词的长度
28 | for (int i = index; i >= 0; i--) {
29 | if (s.charAt(i) == ' ') {
30 | break;
31 | }
32 | count++;
33 | }
34 | return count;
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/string/N168convertToTitle.java:
--------------------------------------------------------------------------------
1 | package leetcode.string;
2 |
3 | /**
4 | * 给定一个正整数,返回它在 Excel 表中相对应的列名称。
5 | *
6 | * 例如,
7 | *
8 | * 1 -> A
9 | * 2 -> B
10 | * 3 -> C
11 | * ...
12 | * 26 -> Z
13 | * 27 -> AA
14 | * 28 -> AB
15 | * ...
16 | *
17 | * 示例 1:
18 | *
19 | * 输入: 1
20 | * 输出: "A"
21 | *
22 | * 示例 2:
23 | *
24 | * 输入: 28
25 | * 输出: "AB"
26 | *
27 | * 示例 3:
28 | *
29 | * 输入: 701
30 | * 输出: "ZY"
31 | *
32 | * 来源:力扣(LeetCode)
33 | * 链接:https://leetcode-cn.com/problems/excel-sheet-column-title
34 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
35 | */
36 |
37 | public class N168convertToTitle {
38 |
39 | public static void main(String[] args) {
40 | String res = new N168convertToTitle().convertToTitle(52);
41 | System.out.println(res);
42 | }
43 |
44 | // TODO: 2019-09-24
45 | public String convertToTitle(int n) {
46 | StringBuffer res = new StringBuffer();
47 |
48 | while (n > 26) {
49 | int tmp = (n-1) / 26;
50 |
51 | res.append((char)(tmp+64));
52 | n = n % 26;
53 | }
54 | res.append((char)(n+64));
55 | return res.toString();
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/FindTheKthMin.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import java.util.Stack;
4 |
5 | public class FindTheKthMin {
6 | public TreeNode KthNode(TreeNode pRoot, int k){
7 |
8 | Stack stack = new Stack<>();
9 | int count = 0;
10 |
11 | TreeNode cur = pRoot;
12 |
13 | while (cur != null || !stack.empty()){
14 |
15 | while (cur!=null){
16 | stack.add(cur);
17 | cur = cur.left;
18 |
19 | }
20 | cur = stack.pop();
21 | count++;
22 | if(count == k){
23 | return cur;
24 | }
25 | cur = cur.right;
26 |
27 | }
28 |
29 | return cur;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/IsHouXuSouSuo.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | public class IsHouXuSouSuo {
4 | public static boolean VerifySquenceOfBST(int [] sequence) {
5 | if(sequence == null ||sequence.length == 0){
6 | return false;
7 | }
8 | return isHouXuSouSuo(sequence,0,sequence.length-1);
9 |
10 | }
11 |
12 | private static boolean isHouXuSouSuo(int[] sequence, int start, int end) {
13 | //递归终止条件
14 | if(start>=end){
15 | return true;
16 | }
17 | int i = start;
18 | while (sequence[i] inorderTraversal(TreeNode root) {
19 | List list = new ArrayList<>();
20 |
21 | if (root == null) {
22 | return list;
23 | }
24 | Stack stack = new Stack<>();
25 | while (!stack.empty() || root != null) {
26 |
27 | if (root != null) {
28 | stack.push(root);
29 | root = root.left;
30 | } else {
31 | root = stack.pop();
32 | list.add(root.val);
33 | root = root.right;
34 |
35 | }
36 | }
37 | return list;
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N100IsSameTree.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定两个二叉树,编写一个函数来检验它们是否相同。
5 | *
6 | * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
7 | *
8 | * 示例 1:
9 | *
10 | * 输入: 1 1
11 | * / \ / \
12 | * 2 3 2 3
13 | *
14 | * [1,2,3], [1,2,3]
15 | *
16 | * 输出: true
17 | *
18 | * 示例 2:
19 | *
20 | * 输入: 1 1
21 | * / \
22 | * 2 2
23 | *
24 | * [1,2], [1,null,2]
25 | *
26 | * 输出: false
27 | *
28 | * 示例 3:
29 | *
30 | * 输入: 1 1
31 | * / \ / \
32 | * 2 1 1 2
33 | *
34 | * [1,2,1], [1,1,2]
35 | *
36 | * 输出: false
37 | *
38 | * 来源:力扣(LeetCode) 100
39 | * 链接:https://leetcode-cn.com/problems/same-tree
40 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
41 | */
42 | public class N100IsSameTree {
43 | public boolean isSameTree(TreeNode p, TreeNode q) {
44 | if(p == null && q == null){
45 | return true;
46 | }
47 | if(p == null || q == null){
48 | return false;
49 | }
50 | if(p.val != q.val){
51 | return false;
52 | }
53 | return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N101isSymmetric.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | public class N101isSymmetric {
4 | public boolean isSymmetric(TreeNode root) {
5 | if (root == null) {
6 | return true;
7 | }
8 | return isSymmetric(root.left, root.right);
9 |
10 | }
11 |
12 | private boolean isSymmetric(TreeNode root1, TreeNode root2) {
13 | if (root1 == null && root2 == null) {
14 | return true;
15 | }
16 | if (root1 == null || root2 == null) {
17 | return false;
18 | }
19 |
20 |
21 | if (root1.val != root2.val) {
22 | return false;
23 | }
24 | return isSymmetric(root1.left, root2.right) && isSymmetric(root1.right, root2.left);
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N104maxDepth.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉树,找出其最大深度。
5 | *
6 | * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
7 | *
8 | * 说明: 叶子节点是指没有子节点的节点。
9 | *
10 | * 示例:
11 | * 给定二叉树 [3,9,20,null,null,15,7],
12 | *
13 | * 3
14 | * / \
15 | * 9 20
16 | * / \
17 | * 15 7
18 | *
19 | * maxDepth(TreeNode root)表示这棵树的最大深度。
20 | * maxDepth(TreeNode root.left)表示这棵树的左子树的最大深度。
21 | * maxDepth(TreeNode root.right)表示这棵树的右子树的最大深度。
22 | * maxDepth(TreeNode root) = Math.max( maxDepth(TreeNode root.left),maxDepth(TreeNode root.right))+1
23 | *
24 | * 返回它的最大深度 3 。
25 | *
26 | * 来源:力扣(LeetCode)
27 | * 链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree
28 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
29 | */
30 | public class N104maxDepth {
31 |
32 | public int maxDepth(TreeNode root) {
33 | if(root == null){
34 | return 0;
35 | }
36 | return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N108SortedArrayToBST.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 | /*
3 | 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
4 |
5 | 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
6 |
7 | 示例:
8 |
9 | 给定有序数组: [-10,-3,0,5,9],
10 |
11 | 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
12 |
13 | 0
14 | / \
15 | -3 9
16 | / /
17 | -10 5
18 |
19 | 来源:力扣(LeetCode)
20 | 链接:https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree
21 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22 | */
23 |
24 | public class N108SortedArrayToBST {
25 |
26 | /*
27 | 按照二分的思想。中点作为根节点。
28 | 中点左边的数作为左子树,中点右边的数作为右子树。
29 | */
30 | public TreeNode sortedArrayToBST(int[] nums) {
31 | if (nums == null || nums.length == 0) {
32 | return null;
33 | }
34 | return help(nums, 0, nums.length - 1);
35 |
36 | }
37 |
38 |
39 | private TreeNode help(int[] nums, int start, int end) {
40 | if (start > end) {
41 | return null;
42 | }
43 | int mid = start + (end - start) / 2;
44 | TreeNode node = new TreeNode(nums[mid]);
45 | node.left = help(nums, start, mid - 1);
46 | node.right = help(nums, mid + 1, end);
47 | return node;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N110isBalanced.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉树,判断它是否是高度平衡的二叉树。
5 | *
6 | * 本题中,一棵高度平衡二叉树定义为:
7 | *
8 | * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
9 | *
10 | * 示例 1:
11 | *
12 | * 给定二叉树 [3,9,20,null,null,15,7]
13 | *
14 | * 3
15 | * / \
16 | * 9 20
17 | * / \
18 | * 15 7
19 | *
20 | * 返回 true 。
21 | *
22 | * 示例 2:
23 | *
24 | * 给定二叉树 [1,2,2,3,3,null,null,4,4]
25 | *
26 | * 1
27 | * / \
28 | * 2 2
29 | * / \
30 | * 3 3
31 | * / \
32 | * 4 4
33 | *
34 | * 返回 false 。
35 | *
36 | * 来源:力扣(LeetCode)
37 | * 链接:https://leetcode-cn.com/problems/balanced-binary-tree
38 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
39 | */
40 | public class N110isBalanced {
41 | /*
42 | 以前序遍历的方式递归的检查每一个节点是否满足平衡二叉树的定义
43 | */
44 | public boolean isBalanced(TreeNode root) {
45 | if(root == null){
46 | return true;
47 | }
48 | if(Math.abs(dep(root.left) - dep(root.right))>1){
49 | return false;
50 | }
51 | return isBalanced(root.left)&&isBalanced(root.right);
52 |
53 | }
54 |
55 |
56 |
57 | private int dep(TreeNode root){
58 | if(root == null){
59 | return 0;
60 | }
61 | return Math.max(dep(root.left),dep(root.right))+1;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N111minDepth.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | public class N111minDepth {
4 | /*
5 | 和求最大深度有点不一样的深度是。求最小深度需要判断一下左节点或者右节点是否为null。
6 | 因为如果根的左节点或者右节点为null,是不满足根到叶子节点这个定义的。
7 | */
8 |
9 | public int minDepth(TreeNode root) {
10 |
11 | if (root == null) {
12 | return 0;
13 | }
14 | int left = minDepth(root.left);
15 | int right = minDepth(root.right);
16 | if (left == 0 || right == 0) {
17 | return left + right + 1;
18 | }
19 | return Math.min(left, right) + 1;
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N112hasPathSum.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
5 | *
6 | * 说明: 叶子节点是指没有子节点的节点。
7 | *
8 | * 示例:
9 | * 给定如下二叉树,以及目标和 sum = 22,
10 | *
11 | * 5
12 | * / \
13 | * 4 8
14 | * / / \
15 | * 11 13 4
16 | * / \ \
17 | * 7 2 1
18 | *
19 | * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
20 | *
21 | * 来源:力扣(LeetCode)
22 | * 链接:https://leetcode-cn.com/problems/path-sum
23 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
24 | */
25 |
26 | /*
27 |
28 | */
29 | public class N112hasPathSum {
30 | public boolean hasPathSum(TreeNode root, int sum) {
31 | if(root == null){
32 | return false;
33 | }
34 | if(root.left == null && root.right == null && sum == root.val){
35 | return true;
36 | }
37 |
38 | return hasPathSum( root.left, sum-root.val) || hasPathSum( root.right, sum-root.val);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N113PathSum.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 给定一个二叉树和一个目标和,找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
8 | *
9 | * 说明: 叶子节点是指没有子节点的节点。
10 | *
11 | * 示例:
12 | * 给定如下二叉树,以及目标和 sum = 22,
13 | *
14 | * 5
15 | * / \
16 | * 4 8
17 | * / / \
18 | * 11 13 4
19 | * / \ / \
20 | * 7 2 5 1
21 | *
22 | * 返回:
23 | *
24 | * [
25 | * [5,4,11,2],
26 | * [5,8,4,5]
27 | * ]
28 | *
29 | * 来源:力扣(LeetCode) 113
30 | * 链接:https://leetcode-cn.com/problems/path-sum-ii
31 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
32 | */
33 |
34 | public class N113PathSum {
35 | List> lists = new ArrayList<>();
36 | public List> pathSum(TreeNode root, int sum) {
37 | if(root == null){
38 | return lists;
39 | }
40 | process(root,sum,new ArrayList<>());
41 | return lists;
42 |
43 | }
44 | private void process(TreeNode root, int sum, Listlist){
45 | if(root == null){
46 | return;
47 | }
48 | sum -= root.val;
49 | list.add(root.val);
50 | if(root.left == null && root.right == null && 0 == sum){
51 | lists.add(new ArrayList<>(list));
52 | }
53 | process(root.left,sum ,list);
54 | process(root.right,sum ,list);
55 | //java中的list传递的是引用,所以递归结束后,要把之前加入的元素删除,
56 | list.remove(list.size()-1);
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N114flatten.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉树,原地将它展开为链表。
5 | *
6 | * 例如,给定二叉树
7 | *
8 | * 1
9 | * / \
10 | * 2 5
11 | * / \ \
12 | * 3 4 6
13 | * 将其展开为:
14 | *
15 | * 1
16 | * \
17 | * 2
18 | * \
19 | * 3
20 | * \
21 | * 4
22 | * \
23 | * 5
24 | * \
25 | * 6
26 | *
27 | * 来源:力扣(LeetCode)
28 | * 链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
29 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
30 | */
31 | public class N114flatten {
32 | public void flatten(TreeNode root) {
33 | while (root != null){
34 | if(root.left == null){
35 | root = root.right;
36 | } else {
37 | TreeNode left = root.left;
38 | while(left.right != null){
39 | left = left.right;
40 | }
41 | left.right = root.right;
42 | root.right = root.left;
43 | root.left = null;
44 |
45 | }
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N129SumNumbers.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉树,它的每个结点都存放一个 0-9 的数字,每条从根到叶子节点的路径都代表一个数字。
5 | *
6 | * 例如,从根到叶子节点路径 1->2->3 代表数字 123。
7 | *
8 | * 计算从根到叶子节点生成的所有数字之和。
9 | *
10 | * 说明: 叶子节点是指没有子节点的节点。
11 | *
12 | * 示例 1:
13 | *
14 | * 输入: [1,2,3]
15 | * 1
16 | * / \
17 | * 2 3
18 | * 输出: 25
19 | * 解释:
20 | * 从根到叶子节点路径 1->2 代表数字 12.
21 | * 从根到叶子节点路径 1->3 代表数字 13.
22 | * 因此,数字总和 = 12 + 13 = 25.
23 | *
24 | * 示例 2:
25 | *
26 | * 输入: [4,9,0,5,1]
27 | * 4
28 | * / \
29 | * 9 0
30 | * / \
31 | * 5 1
32 | * 输出: 1026
33 | * 解释:
34 | * 从根到叶子节点路径 4->9->5 代表数字 495.
35 | * 从根到叶子节点路径 4->9->1 代表数字 491.
36 | * 从根到叶子节点路径 4->0 代表数字 40.
37 | * 因此,数字总和 = 495 + 491 + 40 = 1026.
38 | *
39 | * 来源:力扣(LeetCode) 129
40 | * 链接:https://leetcode-cn.com/problems/sum-root-to-leaf-numbers
41 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
42 | */
43 | public class N129SumNumbers {
44 |
45 | public int sumNumbers(TreeNode root) {
46 | int sum = 0;
47 | if(root == null){
48 | return sum;
49 | }
50 |
51 | return help(root,0);
52 | }
53 |
54 |
55 | private int help(TreeNode root, int sum){
56 | if(root == null){
57 | return 0;
58 | }
59 | sum = sum*10 + root.val;
60 | if(root.left == null && root.right == null){
61 | return sum;
62 | }
63 |
64 | return help(root.left,sum)+help(root.right,sum);
65 | }
66 | }
67 |
68 | // TODO: 2019-08-14 method 2 and method3
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N226InvertTree.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 翻转一棵二叉树。
5 | *
6 | * 示例:
7 | *
8 | * 输入:
9 | *
10 | * 4
11 | * / \
12 | * 2 7
13 | * / \ / \
14 | * 1 3 6 9
15 | *
16 | * 输出:
17 | *
18 | * 4
19 | * / \
20 | * 7 2
21 | * / \ / \
22 | * 9 6 3 1
23 | *
24 | *
25 | * invertTree(TreeNode root)表示翻转二叉树
26 | *
27 | * invertTree(TreeNode root.left)表示翻转左子树
28 | *
29 | * invertTree(TreeNode root.right)表示翻转左子树
30 | *
31 | *
32 | * 来源:力扣(LeetCode)
33 | * 链接:https://leetcode-cn.com/problems/invert-binary-tree
34 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
35 | */
36 | public class N226InvertTree {
37 | public TreeNode invertTree(TreeNode root) {
38 | if(root == null){
39 | return root;
40 | }
41 | TreeNode left = root.left;
42 | root.left = invertTree(root.right);
43 | root.right = invertTree(left);
44 | return root;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N235lowestCommonAncestor.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
5 | *
6 | * 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,
7 | * 满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
8 | *
9 | * 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
10 | *
11 | *
12 | *
13 | * 示例 1:
14 | *
15 | * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
16 | * 输出: 6
17 | * 解释: 节点 2 和节点 8 的最近公共祖先是 6。
18 | *
19 | * 示例 2:
20 | *
21 | * 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
22 | * 输出: 2
23 | * 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
24 | *
25 | * 来源:力扣(LeetCode)
26 | * 链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree
27 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
28 | */
29 |
30 | public class N235lowestCommonAncestor {
31 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
32 | if(root == null || root == p || root == q){
33 | return root;
34 | }
35 | if(root.val > p.val && root.val > q.val){
36 | return lowestCommonAncestor(root.left, p, q);
37 | }
38 | if(root.val < p.val && root.val < q.val){
39 | return lowestCommonAncestor(root.right, p, q);
40 | }
41 | return root;
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N337rob.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。
5 | * 这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,
6 | * 聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。
7 | *
8 | * 计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。
9 | *
10 | * 示例 1:
11 | *
12 | * 输入: [3,2,3,null,3,null,1]
13 | *
14 | * 3
15 | * / \
16 | * 2 3
17 | * \ \
18 | * 3 1
19 | *
20 | * 输出: 7
21 | * 解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.
22 | *
23 | * 示例 2:
24 | *
25 | * 输入: [3,4,5,1,3,null,1]
26 | *
27 | * 3
28 | * / \
29 | * 4 5
30 | * / \ \
31 | * 1 3 1
32 | *
33 | * 输出: 9
34 | * 解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.
35 | *
36 | * 来源:力扣(LeetCode)
37 | * 链接:https://leetcode-cn.com/problems/house-robber-iii
38 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
39 | */
40 |
41 | public class N337rob {
42 | public int rob(TreeNode root) {
43 | if (root == null) {
44 | return 0;
45 | }
46 | int val1 = root.val;
47 |
48 | if (root.left != null) {
49 | val1 += rob(root.left.left) + rob(root.left.right);
50 | }
51 |
52 | if (root.right != null) {
53 | val1 += rob(root.right.left) + rob(root.right.right);
54 | }
55 | int val2 = rob(root.left) + rob(root.right);
56 | return val1 > val2 ? val1 : val2;
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N404sumOfLeftLeaves.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 计算给定二叉树的所有左叶子之和。
5 | *
6 | * 示例:
7 | *
8 | * 3
9 | * / \
10 | * 9 20
11 | * / \
12 | * 15 7
13 | *
14 | * 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
15 | *
16 | * 来源:力扣(LeetCode)
17 | * 链接:https://leetcode-cn.com/problems/sum-of-left-leaves
18 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
19 | */
20 | public class N404sumOfLeftLeaves {
21 | public int sumOfLeftLeaves(TreeNode root) {
22 | if (root == null) {
23 | return 0;
24 | }
25 | int sum = 0;
26 | if (isLeftLeave(root.left)) {
27 | sum += root.left.val;
28 | } else {
29 | sum += sumOfLeftLeaves(root.left);
30 | }
31 | sum += sumOfLeftLeaves(root.right);
32 | return sum;
33 | }
34 |
35 | private boolean isLeftLeave(TreeNode treeNode) {
36 | return treeNode != null && (treeNode.left == null && treeNode.right == null);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N530getMinimumDifference.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | public class N530getMinimumDifference {
4 | /**
5 | * 给定一个所有节点为非负值的二叉搜索树,求树中任意两节点的差的绝对值的最小值。
6 | *
7 | * 示例 :
8 | *
9 | * 输入:
10 | *
11 | * 1
12 | * \
13 | * 3
14 | * /
15 | * 2
16 | *
17 | * 输出:
18 | * 1
19 | *
20 | * 解释:
21 | * 最小绝对差为1,其中 2 和 1 的差的绝对值为 1(或者 2 和 3)。
22 | *
23 | * 注意: 树中至少有2个节点。
24 | *
25 | * 来源:力扣(LeetCode)
26 | * 链接:https://leetcode-cn.com/problems/minimum-absolute-difference-in-bst
27 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
28 | *
29 | * @param root
30 | * @return
31 | */
32 |
33 | int res = Integer.MAX_VALUE;
34 |
35 | TreeNode pre = null;
36 |
37 | public int getMinimumDifference(TreeNode root) {
38 | help(root);
39 | return res;
40 | }
41 |
42 | /*
43 | 思路:前序遍历,找差值
44 | */
45 |
46 | private void help(TreeNode root) {
47 | if (root.left != null) {
48 | help(root.left);
49 | }
50 | if (pre != null) {
51 | res = res < (root.val - pre.val) ? res : (root.val - pre.val);
52 | }
53 | pre = root;
54 | if (root.right != null) {
55 | help(root.right);
56 | }
57 |
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N538convertBST.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),
5 | * 使得每个节点的值是原来的节点值加上所有大于它的节点值之和。
6 | *
7 | * 例如:
8 | *
9 | * 输入: 二叉搜索树:
10 | * 5
11 | * / \
12 | * 2 13
13 | *
14 | * 输出: 转换为累加树:
15 | * 18
16 | * / \
17 | * 20 13
18 | *
19 | * 来源:力扣(LeetCode)
20 | * 链接:https://leetcode-cn.com/problems/convert-bst-to-greater-tree
21 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
22 | */
23 |
24 | public class N538convertBST {
25 |
26 | int sum = 0;
27 |
28 | public TreeNode convertBST(TreeNode root) {
29 | if (root == null) {
30 | return null;
31 | }
32 | convertBST(root.right);
33 | sum += root.val;
34 | root.val = sum;
35 | convertBST(root.left);
36 | return root;
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N572isSubtree.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
5 | *
6 | * 示例 1:
7 | * 给定的树 s:
8 | *
9 | * 3
10 | * / \
11 | * 4 5
12 | * / \
13 | * 1 2
14 | *
15 | * 给定的树 t:
16 | *
17 | * 4
18 | * / \
19 | * 1 2
20 | *
21 | * 返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
22 | *
23 | * 示例 2:
24 | * 给定的树 s:
25 | *
26 | * 3
27 | * / \
28 | * 4 5
29 | * / \
30 | * 1 2
31 | * /
32 | * 0
33 | *
34 | * 给定的树 t:
35 | *
36 | * 4
37 | * / \
38 | * 1 2
39 | *
40 | * 返回 false。
41 | *
42 | * 来源:力扣(LeetCode) 572
43 | * 链接:https://leetcode-cn.com/problems/subtree-of-another-tree
44 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
45 | */
46 | public class N572isSubtree {
47 |
48 | public boolean isSubtree(TreeNode s, TreeNode t) {
49 | if(s == null){
50 | return false;
51 | }
52 | if(equal(s,t)){
53 | return true;
54 | }
55 |
56 | return isSubtree(s.left, t) || isSubtree(s.right, t);
57 | }
58 |
59 | private boolean equal(TreeNode s, TreeNode t) {
60 | if (s == null && t == null) {
61 | return true;
62 | }
63 | if (s == null || t == null || s.val != t.val) {
64 | return false;
65 | }
66 |
67 | return equal(s.left, t.left) && equal(s.right, t.right);
68 |
69 |
70 |
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N653findTarget.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | /**
7 | * 给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。
8 | *
9 | * 案例 1:
10 | *
11 | * 输入:
12 | * 5
13 | * / \
14 | * 3 6
15 | * / \ \
16 | * 2 4 7
17 | *
18 | * Target = 9
19 | *
20 | * 输出: True
21 | *
22 | *
23 | *
24 | * 案例 2:
25 | *
26 | * 输入:
27 | * 5
28 | * / \
29 | * 3 6
30 | * / \ \
31 | * 2 4 7
32 | *
33 | * Target = 28
34 | *
35 | * 输出: False
36 | *
37 | * 来源:力扣(LeetCode)
38 | * 链接:https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst
39 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
40 | */
41 | public class N653findTarget {
42 |
43 | Set set = new HashSet<>();
44 |
45 | public boolean findTarget(TreeNode root, int k) {
46 | if (root == null) {
47 | return false;
48 | }
49 | if (set.contains(k - root.val)) {
50 | return true;
51 | }
52 | set.add(root.val);
53 | return findTarget(root.left, k) || findTarget(root.right, k);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N654constructMaximumBinaryTree.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
5 | *
6 | * 二叉树的根是数组中的最大元素。
7 | * 左子树是通过数组中最大值左边部分构造出的最大二叉树。
8 | * 右子树是通过数组中最大值右边部分构造出的最大二叉树。
9 | *
10 | * 通过给定的数组构建最大二叉树,并且输出这个树的根节点。
11 | *
12 | *
13 | *
14 | * 示例 :
15 | *
16 | * 输入:[3,2,1,6,0,5]
17 | * 输出:返回下面这棵树的根节点:
18 | *
19 | * 6
20 | * / \
21 | * 3 5
22 | * \ /
23 | * 2 0
24 | * \
25 | * 1
26 | *
27 | *
28 | *
29 | * 提示:
30 | *
31 | * 给定的数组的大小在 [1, 1000] 之间。
32 | *
33 | * 来源:力扣(LeetCode)
34 | * 链接:https://leetcode-cn.com/problems/maximum-binary-tree
35 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
36 | */
37 | public class N654constructMaximumBinaryTree {
38 | public TreeNode constructMaximumBinaryTree(int[] nums) {
39 | if (nums.length == 0) {
40 | return null;
41 | }
42 | TreeNode node = null;
43 | for (int num : nums) {
44 | node = process(node, num);
45 |
46 | }
47 | return node;
48 |
49 | }
50 |
51 | private TreeNode process(TreeNode root, int num) {
52 | TreeNode node = new TreeNode(num);
53 | if (root == null) {
54 | return node;
55 | }
56 | if (root.val < num) {
57 | node.left = root;
58 | return node;
59 | } else {
60 | root.right = process(root.right, num);
61 | return root;
62 |
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N669trimBST.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。
5 | * 你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
6 | *
7 | * 示例 1:
8 | *
9 | * 输入:
10 | * 1
11 | * / \
12 | * 0 2
13 | *
14 | * L = 1
15 | * R = 2
16 | *
17 | * 输出:
18 | * 1
19 | * \
20 | * 2
21 | *
22 | * 示例 2:
23 | *
24 | * 输入:
25 | * 3
26 | * / \
27 | * 0 4
28 | * \
29 | * 2
30 | * /
31 | * 1
32 | *
33 | * L = 1
34 | * R = 3
35 | *
36 | * 输出:
37 | * 3
38 | * /
39 | * 2
40 | * /
41 | * 1
42 | *
43 | * 来源:力扣(LeetCode)
44 | * 链接:https://leetcode-cn.com/problems/trim-a-binary-search-tree
45 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
46 | */
47 |
48 | public class N669trimBST {
49 | public TreeNode trimBST(TreeNode root, int L, int R) {
50 | if (root == null) {
51 | return null;
52 | }
53 | if (root.val > R) {
54 | return trimBST(root.left, L, R);
55 | }
56 | if (root.val < L) {
57 | return trimBST(root.right, L, R);
58 | }
59 |
60 | root.left = trimBST(root.left, L, R);
61 | root.right = trimBST(root.right, L, R);
62 | return root;
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/N671findSecondMinimumValue.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * 给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,
5 | * 那么这个节点的值不大于它的子节点的值。
6 | *
7 | * 给出这样的一个二叉树,你需要输出所有节点中的第二小的值。如果第二小的值不存在的话,输出 -1 。
8 | *
9 | * 示例 1:
10 | *
11 | * 输入:
12 | * 2
13 | * / \
14 | * 2 5
15 | * / \
16 | * 5 7
17 | *
18 | * 输出: 5
19 | * 说明: 最小的值是 2 ,第二小的值是 5 。
20 | *
21 | * 示例 2:
22 | *
23 | * 输入:
24 | * 2
25 | * / \
26 | * 2 2
27 | *
28 | * 输出: -1
29 | * 说明: 最小的值是 2, 但是不存在第二小的值。
30 | *
31 | * 来源:力扣(LeetCode)
32 | * 链接:https://leetcode-cn.com/problems/second-minimum-node-in-a-binary-tree
33 | * 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
34 | */
35 |
36 | public class N671findSecondMinimumValue {
37 | public int findSecondMinimumValue(TreeNode root) {
38 | if (root == null || (root.left == null && root.right == null)) {
39 | return -1;
40 | }
41 |
42 | int left = root.left.val;
43 | int right = root.right.val;
44 |
45 | if (left == root.val) {
46 | left = findSecondMinimumValue(root.left);
47 | }
48 |
49 | if (right == root.val) {
50 | right = findSecondMinimumValue(root.right);
51 | }
52 |
53 | if (left != -1 && right != -1) {
54 | return Math.min(left, right);
55 | }
56 | if (left != -1) {
57 | return left;
58 | }
59 | return right;
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/NextNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * created by reedfan on 2019/5/13 0013
5 | */
6 | public class NextNode {
7 | public TreeLinkNode GetNext(TreeLinkNode pNode) {
8 | if(pNode == null){
9 | return null;
10 | }
11 | if(pNode.right!=null){
12 | TreeLinkNode node = pNode.right;
13 | while (node!=null){
14 | node = node.left;
15 | }
16 | return node;
17 | }
18 |
19 |
20 | return pNode;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/Node.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/9/27
6 | * Time: 11:33
7 | */
8 |
9 | public class Node {
10 | private int data;
11 | private Node leftNode;
12 | private Node rightNode;
13 | public Node(int data, Node leftNode, Node rightNode) {
14 | this.setData(data);
15 | this.leftNode = leftNode;
16 | this.rightNode = rightNode;
17 | }
18 | public int getData() { return data; }
19 | public void setData(int data) { this.data = data; }
20 | public Node getLeftNode() { return leftNode; }
21 | public void setLeftNode(Node leftNode) { this.leftNode = leftNode; }
22 | public Node getRightNode() { return rightNode; }
23 | public void setRightNode(Node rightNode) { this.rightNode = rightNode; }
24 |
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/Nqueen.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import org.junit.Test;
4 |
5 | public class Nqueen {
6 |
7 | @Test
8 | public void test(){
9 | System.out.println(num(4));
10 |
11 | }
12 |
13 |
14 | public int num(int n){
15 | if(n < 1){
16 | return 0;
17 | }
18 | int[] record = new int[n];
19 | return process(0,record,n);
20 | }
21 |
22 |
23 | //record[i]表示第行皇后所在的列
24 | public int process(int i, int[] record, int n){
25 |
26 | //终止条件
27 | if(i==n){
28 | return 1;
29 | }
30 | int res = 0;
31 | //看每一列是否符合条件
32 | for (int j = 0; j < n ; j++) {
33 | if (isValid(record,i,j)){
34 | record[i] = j;
35 | res += process(i+1, record, n);
36 | }
37 |
38 | }
39 | return res;
40 |
41 | }
42 |
43 |
44 | public boolean isValid(int[] record,int i,int j){
45 | for (int k = 0; k > pathSum(TreeNode root, int target) {
21 | ArrayList> lists = new ArrayList>();
22 | Stack stack = new Stack<>();
23 | int pathValue = 0;
24 | preOrder(root, pathValue, target, stack, lists);
25 | return lists;
26 | }
27 |
28 | private static void preOrder(TreeNode node, int pathValur, int sum, Stack path, ArrayList> result) {
29 | if (node == null) {
30 | return;
31 | }
32 | pathValur += node.val;
33 | path.add(node.val);
34 | if (node.left == null && node.right == null && pathValur == sum) {
35 | result.add(new ArrayList<>(path));
36 | }
37 | preOrder(node.left, pathValur, sum, path, result);
38 | preOrder(node.right, pathValur, sum, path, result);
39 | //回退 剪枝
40 | pathValur -= node.val;
41 | path.pop();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/PingHengErChaShu.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * created by reedfan on 2019/4/23 0023
5 | */
6 | public class PingHengErChaShu {
7 | public boolean IsBalanced_Solution(TreeNode root) {
8 | if(root == null){
9 | return true;
10 | }
11 | if(Math.abs(dep(root.left)-dep(root.right))>1){
12 | return false;
13 | }
14 |
15 | return IsBalanced_Solution(root.left)&&IsBalanced_Solution(root.right);
16 | }
17 |
18 | private int dep(TreeNode root){
19 | if(root == null){
20 | return 0;
21 | }
22 | return dep(root.left)>dep(root.right)?dep(root.left):dep(root.right)+1;
23 |
24 | }
25 |
26 |
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/PostOrderUnRec.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Stack;
5 |
6 | public class PostOrderUnRec {
7 | public ArrayList postorderTraversal(TreeNode root) {
8 | ArrayList list = new ArrayList<>();
9 | if(root == null){
10 | return list;
11 | }
12 | Stack stack1 = new Stack<>();
13 | Stack stack2 = new Stack<>();
14 | stack1.add(root);
15 | while (!stack1.isEmpty()){
16 | TreeNode tmp = stack1.pop();
17 | stack2.add(tmp);
18 | if(tmp.left!=null){
19 | stack1.add(tmp.left);
20 | }
21 | if(tmp.right!=null){
22 | stack1.add(tmp.right);
23 | }
24 |
25 | }
26 | while (!stack2.isEmpty()){
27 | list.add(stack2.pop().val);
28 | }
29 | return list;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/PreorderTraversal.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Stack;
5 |
6 | public class PreorderTraversal {
7 | public ArrayList preorderTraversal(TreeNode root) {
8 | ArrayList list = new ArrayList<>();
9 | if(root ==null){
10 | return list;
11 | }
12 | Stack stack = new Stack<>();
13 | stack.add(root);
14 | while (!stack.isEmpty()){
15 | TreeNode treeNode = stack.pop();
16 | list.add(treeNode.val);
17 | if(treeNode.right!=null){
18 | stack.add(treeNode.right);
19 | }
20 | if(treeNode.left!=null){
21 | stack.add(treeNode.left);
22 | }
23 |
24 | }
25 | return list;
26 | }
27 |
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/PrintTreeFromUpToDownFromLeftToRight.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedList;
5 |
6 | /**
7 | * created by reedfan on 2019/4/23 0023
8 | */
9 | public class PrintTreeFromUpToDownFromLeftToRight {
10 |
11 | /*
12 | 45ms
13 | */
14 | ArrayList> Print(TreeNode pRoot) {
15 | ArrayList> arrayLists = new ArrayList>();
16 | if(pRoot == null){
17 | return arrayLists;
18 | }
19 |
20 | LinkedList linkedList = new LinkedList();
21 | linkedList.add(pRoot);
22 | int size,cur;
23 |
24 | while (!linkedList.isEmpty()){
25 | cur = 0;
26 | size = linkedList.size();
27 | ArrayListarrayList = new ArrayList();
28 | while (cur-1 ; i--) {
29 | if(str[i] == str[j]){
30 | dp[i][j] = dp[i+1][j-1];
31 | }else {
32 | dp[i][j] = Math.min(dp[i+1][j],dp[i][j-1])+1;
33 | }
34 |
35 | }
36 |
37 | }
38 | return dp;
39 |
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/TreeLinkNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * created by reedfan on 2019/5/13 0013
5 | */
6 | public class TreeLinkNode {
7 | int val;
8 | TreeLinkNode left = null;
9 | TreeLinkNode right = null;
10 | TreeLinkNode next = null;
11 |
12 | TreeLinkNode(int val) {
13 | this.val = val;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/leetcode/tree/TreeNode.java:
--------------------------------------------------------------------------------
1 | package leetcode.tree;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/17
6 | * Time: 11:41
7 | */
8 |
9 | public class TreeNode {
10 | public int val = 0;
11 | public TreeNode left = null;
12 | public TreeNode right = null;
13 |
14 | public TreeNode(int val) {
15 | this.val = val;
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/decorator/Clienter.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.decorator;
2 |
3 | public class Clienter {
4 | public static void main(String[] args) {
5 | House reedHouse = new ReedHouse();
6 | House decorator = new Decorator(reedHouse);
7 | decorator.output();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/decorator/Decorator.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.decorator;
2 |
3 | public class Decorator implements House {
4 | private House house;
5 |
6 | public Decorator(House house) {
7 | this.house = house;
8 | }
9 | @Override
10 | public void output() {
11 | System.out.println("这是针对房子的前段装饰增强");
12 | house.output();
13 | System.out.println("这是针对房子的后段装饰增强");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/decorator/House.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.decorator;
2 |
3 | /**
4 | * 目标接口:房子
5 | */
6 | public interface House {
7 | void output();
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/decorator/JuneHouse.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.decorator;
2 |
3 | public class JuneHouse implements House{
4 | @Override
5 | public void output() {
6 | System.out.println("这是june的房子");
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/decorator/ReedHouse.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.decorator;
2 |
3 | public class ReedHouse implements House {
4 | @Override
5 | public void output() {
6 | System.out.println("这是reed的房子");
7 |
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/facade/Client.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.facade;
2 |
3 | import shejimoshi.facade.facade.Computer;
4 |
5 | /**
6 | * https://www.cnblogs.com/lthIU/p/5860607.html
7 | */
8 |
9 | public class Client {
10 | public static void main(String[] args) {
11 | Computer computer = new Computer();
12 | computer.start();
13 | System.out.println("==============");
14 | computer.shutdown();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/facade/children/CPU.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.facade.children;
2 |
3 | public class CPU {
4 |
5 | public void start(){
6 | System.out.println("cpu is start...");
7 | }
8 |
9 | public void shutdown(){
10 | System.out.println("cpu is shutdown...");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/facade/children/Disk.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.facade.children;
2 |
3 | public class Disk {
4 |
5 | public void start(){
6 | System.out.println("disk is start...");
7 | }
8 |
9 | public void shutdown(){
10 | System.out.println("disk is shutdown...");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/facade/children/Memory.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.facade.children;
2 |
3 | public class Memory {
4 |
5 | public void start(){
6 | System.out.println("Memory is start...");
7 | }
8 |
9 | public void shutdown(){
10 | System.out.println("Memory is shutdown...");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/facade/facade/Computer.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.facade.facade;
2 |
3 | import shejimoshi.facade.children.CPU;
4 | import shejimoshi.facade.children.Disk;
5 | import shejimoshi.facade.children.Memory;
6 |
7 | public class Computer {
8 | private CPU cpu;
9 | private Memory memory;
10 | private Disk disk;
11 | public Computer(){
12 | cpu = new CPU();
13 | memory = new Memory();
14 | disk = new Disk();
15 | }
16 | public void start(){
17 | System.out.println("Computer start begin");
18 | cpu.start();
19 | disk.start();
20 | memory.start();
21 | System.out.println("Computer start end");
22 | }
23 |
24 | public void shutdown(){
25 | System.out.println("Computer shutdown begin");
26 | cpu.shutdown();
27 | disk.shutdown();
28 | memory.shutdown();
29 | System.out.println("Computer shutdown end");
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/Singleton.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/26
6 | * Time: 17:13
7 | */
8 |
9 | public class Singleton {
10 |
11 | private Singleton(){ }
12 | private static Singleton singleton = null;
13 | public static Singleton getInstance(){
14 | if(singleton == null){
15 | synchronized (Singleton.class){
16 | if(singleton == null){
17 | singleton = new Singleton();
18 | }
19 |
20 | }
21 | }
22 | return singleton;
23 | }
24 |
25 |
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/Singleton1.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/17
6 | * Time: 22:19
7 | */
8 |
9 | public class Singleton1 {
10 |
11 | private Singleton1(){
12 |
13 | }
14 | private static final Singleton1 singleton = new Singleton1();
15 | public static Singleton1 getSingleton(){
16 | return singleton;
17 | }
18 |
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/Singleton2.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton;
2 |
3 |
4 | /**
5 | * Author 范群松.
6 | * Date:2018/8/17
7 | * Time: 22:28
8 | */
9 |
10 | public class Singleton2 {
11 | private Singleton2(){
12 |
13 | }
14 |
15 | private static Singleton2 singleton2 = null;
16 | public static Singleton2 getSingleton2() {
17 | if(singleton2 == null){
18 | singleton2 = new Singleton2();
19 | }
20 | return singleton2;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/Singleton3.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/8/21
6 | * Time: 20:40
7 | */
8 |
9 | public class Singleton3 {
10 | private Singleton3(){ }
11 | private static Singleton3 singleton3 = null;
12 | public Singleton3 getinstance(){
13 | if(singleton3 == null){
14 | synchronized (Singleton3.class){
15 | if(singleton3 == null){
16 | singleton3 = new Singleton3();
17 | }
18 | }
19 | }
20 | return singleton3;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/st/StaticClass.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton.st;
2 |
3 | /**
4 | * https://blog.csdn.net/mnb65482/article/details/80458571
5 | *
6 | * 1.外部类加载时并不需要立即加载内部类,内部类不被加载则不去加载INSTANCE,故不占内存
7 | * 2.
8 | */
9 |
10 | public class StaticClass {
11 | private StaticClass(){};
12 | private static class StaticClassSc{
13 | private static StaticClass staticClassSc = new StaticClass();
14 | }
15 |
16 | public static StaticClass getInstance(){
17 | return StaticClassSc.staticClassSc;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/st/StaticClassTest.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton.st;
2 |
3 | public class StaticClassTest {
4 | public static void main(String[] args) {
5 | StaticClass sc = StaticClass.getInstance();
6 | StaticClass sc1 = StaticClass.getInstance();
7 | System.out.println(sc == sc1);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/st1/StaticTest.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton.st1;
2 |
3 | /**
4 | * 是一种变种的恶汉模式
5 | *
6 | */
7 |
8 | public class StaticTest {
9 |
10 | private static StaticTest staticTest = null;
11 |
12 | private StaticTest(){
13 |
14 | }
15 | static {
16 | System.out.println("Singleton--我在被调用的时候加载,而且只加载一次");
17 | staticTest = new StaticTest();
18 | }
19 |
20 | public static StaticTest getInstance(){
21 | return staticTest;
22 | }
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/singleton/st1/Test.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.singleton.st1;
2 |
3 | public class Test {
4 | public static void main(String[] args) {
5 | StaticTest.getInstance();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/watcher/ConcreteWatched.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.watcher;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * Author 范群松.
8 | * Date:2018/10/8
9 | * Time: 9:06
10 | */
11 |
12 | public class ConcreteWatched implements Watched {
13 | private List list = new ArrayList();
14 |
15 | public ConcreteWatched() {
16 | super();
17 | }
18 |
19 | public void addWatcher(Watcher watcher) {
20 | list.add(watcher);
21 |
22 | }
23 |
24 | public void removeWatcher(Watcher watcher) {
25 | list.remove(watcher);
26 |
27 | }
28 |
29 | public void notifyWatchers(String str) {
30 | for(Watcher watcher:list){
31 | watcher.update(str);
32 | }
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/watcher/ConcreteWatcher.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.watcher;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/10/8
6 | * Time: 9:04
7 | */
8 |
9 | public class ConcreteWatcher implements Watcher {
10 |
11 | public void update(String str) {
12 | System.out.println(str);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/watcher/Test.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.watcher;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/10/8
6 | * Time: 9:12
7 | */
8 |
9 | public class Test {
10 |
11 | public static void main(String[] args) {
12 | Watched girl = new ConcreteWatched();
13 | Watcher watcher1 = new ConcreteWatcher();
14 | Watcher watcher2 = new ConcreteWatcher();
15 | Watcher watcher3 = new ConcreteWatcher();
16 |
17 | girl.addWatcher(watcher1);
18 | girl.addWatcher(watcher2);
19 | girl.addWatcher(watcher3);
20 |
21 | girl.notifyWatchers("update");
22 | }
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/watcher/Watched.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.watcher;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/10/8
6 | * Time: 9:01
7 | */
8 |
9 | //抽象主题角色,watched被观察
10 | public interface Watched {
11 | public void addWatcher(Watcher watcher);
12 |
13 | public void removeWatcher(Watcher watcher);
14 |
15 | public void notifyWatchers(String str);
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/shejimoshi/watcher/Watcher.java:
--------------------------------------------------------------------------------
1 | package shejimoshi.watcher;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/10/8
6 | * Time: 8:59
7 | */
8 |
9 | //抽象观察者角色
10 | public interface Watcher {
11 | public void update(String str);
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/shujujiegou/BubbleSort.java:
--------------------------------------------------------------------------------
1 | package shujujiegou;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/9/19
8 | * Time: 14:57
9 | */
10 |
11 | public class BubbleSort {
12 |
13 |
14 |
15 | /*
16 | 2, 4, 6, 1, 8, 5, 0
17 |
18 | 8
19 | 2 6, 8
20 |
21 | 冒泡排序 O(n^2)
22 |
23 | */
24 |
25 |
26 |
27 |
28 | public static void main(String[] args) {
29 | int[] arr = {2, 4, 6, 1, 8, 5, 0};
30 | sort(arr);
31 | System.out.println(Arrays.toString(arr));
32 | }
33 |
34 | private static void sort(int[] a) {
35 | int length = a.length;
36 | for (int i = 0; i < length - 1; i++) { //控制循环多少轮
37 | for (int j = 0; j < length - i - 1; j++) { //具体每一轮的循环排序
38 | if (a[j] > a[j + 1]) {
39 | int tmp = a[j];
40 | a[j] = a[j + 1];
41 | a[j + 1] = tmp;
42 | }
43 | }
44 | }
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/shujujiegou/EFCZ.java:
--------------------------------------------------------------------------------
1 | package shujujiegou;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/9/19
6 | * Time: 15:03
7 | */
8 |
9 | public class EFCZ {
10 | public static void main(String[] args) {
11 | int[] a={1,2,3,4,5,6,7,8,9};
12 | int value=binary(a,5);
13 | System.out.println(value);
14 | }
15 |
16 |
17 |
18 | private static int binary(int[] a,int target){
19 | int left = 0;
20 | int right = a.length-1;
21 | int mid = -1;
22 | while (lefta[mid]){
28 | left = mid+1;
29 | }else {
30 | right = mid-1;
31 | }
32 | }
33 | }
34 | return -1;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/shujujiegou/MergeSort.java:
--------------------------------------------------------------------------------
1 | package shujujiegou;
2 |
3 | /**
4 | * Author 范群松.
5 | * Date:2018/9/24
6 | * Time: 16:00
7 | */
8 |
9 | public class MergeSort {
10 |
11 | public static void main(String args[]) {
12 | int[] test = {9, 2, 6, 3, 5, 7, 10, 11, 12};
13 | merSort(test, 0, test.length - 1);
14 | for (int i = 0; i < test.length; i++) {
15 | System.out.print(test[i] + " ");
16 | }
17 | }
18 |
19 | public static void merSort(int[] arr, int left, int right) {
20 | if (left < right) {
21 | int mid = left + (right - left) / 2;
22 | merSort(arr, left, mid); //左边归并排序,使得左子序列有序
23 | merSort(arr, mid + 1, right); //右边归并排序,使得右子序列有序
24 | merge(arr, left, mid, right); //合并两个子序列
25 | }
26 | }
27 |
28 | private static void merge(int[] arr, int left, int mid, int right) {
29 | int[] tmp = new int[right - left + 1];
30 | int i = left;
31 | int j = mid + 1;
32 | int k = 0;
33 | while (i <= mid && j <= right) {
34 | if (arr[i] < arr[j]) {
35 | tmp[k++] = arr[i++];
36 | } else {
37 | tmp[k++] = arr[j++];
38 | }
39 | }
40 | while (i <= mid) {
41 | tmp[k++] = arr[i++];
42 | }
43 | while (j <= right) {
44 | tmp[k++] = arr[j++];
45 | }
46 | //将tmp中的元素全部拷贝到原数组中
47 | for (int k2 = 0; k2 < tmp.length; k2++) {
48 | arr[k2 + left] = tmp[k2];
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/shujujiegou/QuickSort.java:
--------------------------------------------------------------------------------
1 | package shujujiegou;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * Author 范群松.
7 | * Date:2018/9/19
8 | * Time: 11:25
9 | */
10 |
11 | public class QuickSort {
12 | public static void main(String[] args) {
13 | int[] arr = {2, 4, 6, 1, 7, 5, 0, 8, 8, 5};
14 | sort(arr, 0, arr.length - 1);
15 | System.out.println(Arrays.toString(arr));
16 |
17 | }
18 |
19 | public static void sort(int[] a, int low, int high) {
20 | if (low >= high) {
21 | return;
22 | }
23 | int start = low;
24 | int end = high;
25 | int key = a[low];
26 |
27 | while (start < end) {
28 |
29 | while (end > start && a[end] > key) {
30 | end--;
31 | }
32 |
33 | while (end > start && a[start] <= key) {
34 | start++;
35 | }
36 |
37 | if (start < end) {
38 | int tmp = a[start];
39 | a[start] = a[end];
40 | a[end] = tmp;
41 | }
42 | }
43 | //调整key的位置
44 | a[low] = a[start];
45 | a[start] = key;
46 | //对左边进行排序
47 | sort(a, low, start - 1);
48 | //对右边进行排序
49 | sort(a, start + 1, high);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/sql/N176.sql:
--------------------------------------------------------------------------------
1 | /**
2 | 编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。
3 |
4 | +----+--------+
5 | | Id | Salary |
6 | +----+--------+
7 | | 1 | 100 |
8 | | 2 | 200 |
9 | | 3 | 300 |
10 | +----+--------+
11 |
12 | 例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。
13 |
14 | +---------------------+
15 | | SecondHighestSalary |
16 | +---------------------+
17 | | 200 |
18 | +---------------------+
19 |
20 | 来源:力扣(LeetCode)
21 | 链接:https://leetcode-cn.com/problems/second-highest-salary
22 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
23 | */
24 |
25 | SELECT (select DISTINCT Salary from Employee order by Salary desc limit 1,1) as SecondHighestSalary ;
--------------------------------------------------------------------------------
/src/main/java/sql/N177.sql:
--------------------------------------------------------------------------------
1 | /**
2 | 编写一个 SQL 查询,获取 Employee 表中第n高的薪水(Salary) 。
3 |
4 | +----+--------+
5 | | Id | Salary |
6 | +----+--------+
7 | | 1 | 100 |
8 | | 2 | 200 |
9 | | 3 | 300 |
10 | +----+--------+
11 |
12 | 例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。
13 |
14 | +---------------------+
15 | | SecondHighestSalary |
16 | +---------------------+
17 | | 200 |
18 | +---------------------+
19 |
20 | 来源:力扣(LeetCode)
21 | 链接:https://leetcode-cn.com/problems/second-highest-salary
22 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
23 | */
24 |
25 | CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
26 | BEGIN
27 | SET N = N-1;
28 | RETURN (
29 |
30 |
31 | select DISTINCT Salary from Employee order by Salary desc limit N,1
32 |
33 | );
34 | END
--------------------------------------------------------------------------------
/systemdesign.md:
--------------------------------------------------------------------------------
1 | ## 如何搭建一个高可用系统
2 |
3 | 0, redis缓存,使用Memory Cache,避免频繁访问数据库。
4 |
5 | 1,主备/集群模式,防止单点,横向发展,用loadbalancer做负载均衡
6 |
7 | 2,限流,削峰,防止后端压力过大
8 |
9 | 3,熔断机制,类似与限流
10 |
11 | 4,容灾机制,多机房/异地部署
12 |
13 | 5,把项目,拆分成为多个应用小型服务器形式,来进行分布式部署。如大型电商网站会将首页、商铺、订单等拆成不同的产品线,
14 | 分归不同的业务团队负责。
15 |
16 | 6,数据库合适的索引
17 |
18 | 7,cdn加速 [什么是cdn加速](https://blog.csdn.net/qq_40543535/article/details/79071089)
19 |
20 | 8,采用主从复制,读写分离的数据库模式。主库同时负责读取和写入操作,并复制写入到一个或多个从库中,从库只负责读操作。数据库分库分表,做分布式数据库。
21 |
22 | 9.将一些公用的业务抽取出来,比如电商网站的用户管理,商品管理等,这些可复用的业务连接数据库
23 |
24 | ## 如果AB两个系统互相依赖,如何解除依赖
25 | A--->B,同时B--->A
26 | 解除这种双向依赖的话,需要在AB之外增加一个C,用C封装A依赖的B的那部分功能,让A改为依赖C,C依赖B
27 | 然后就是这样A--->C,C---->B,B--->A不过这样依然存在环路依赖
28 |
29 | ## 什么情况用接口,什么情况用消息
30 |
31 | 接口的特点是同步调用,接口实时响应,阻塞等待
32 |
33 | 消息的特点是异步处理,非实时响应,消息发送后则返回,消息队列可以削峰
34 |
35 |
36 | 一般对实时性要求比较高的功能采用接口
37 |
38 | 对实时性要求不高的功能可以采用消息,削峰时可以采用消息
39 |
40 | ## [【Linux】服务器响应变慢的排查步骤](https://blog.csdn.net/reed1991/article/details/54730690)
41 |
42 | ## [如何避免下重复订单](https://www.jianshu.com/p/e618cc818432)
43 |
--------------------------------------------------------------------------------