_children) {
31 | val = _val;
32 | children = _children;
33 | }
34 | }
35 |
36 | ;
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution011.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 盛最多水的容器
6 | * @date: 2019/01/02
7 | */
8 | public class Solution011 {
9 |
10 | /**
11 | * 双指针解法,指向较小数字的指针向指向较大数字的指针方向移动
12 | *
13 | * @param height
14 | * @return
15 | */
16 | public int maxArea(int[] height) {
17 | if (null == height || 2 > height.length) {
18 | return -1;
19 | }
20 |
21 | int i = 0, j = height.length - 1;
22 | int maxArea = 0;
23 | while (i < j) {
24 | maxArea = Math.max(Math.min(height[i], height[j]) * (j - i), maxArea);
25 |
26 | if (height[i] < height[j]) {
27 | ++i;
28 | } else {
29 | --j;
30 | }
31 | }
32 | return maxArea;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution984.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 不含 AAA 或 BBB 的字符串
6 | * @date: 2019/02/12
7 | */
8 | public class Solution984 {
9 | public String strWithout3a3b(int A, int B) {
10 | StringBuilder ans = new StringBuilder(A + B);
11 | char a = 'a', b = 'b';
12 | int i = A, j = B;
13 | if (B > A) {
14 | a = 'b';
15 | b = 'a';
16 | i = B;
17 | j = A;
18 | }
19 | while (i-- > 0) {
20 | ans.append(a);
21 | if (i > j) {
22 | ans.append(a);
23 | --i;
24 | }
25 | if (j > 0) {
26 | ans.append(b);
27 | --j;
28 | }
29 | }
30 | return ans.toString();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution141.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 环形链表
6 | * @date: 2019/01/04
7 | */
8 | public class Solution141 {
9 |
10 | public boolean hasCycle(ListNode head) {
11 | if (null == head) {
12 | return false;
13 | }
14 |
15 | ListNode slow = head, fast = head;
16 | while (null != fast && null != fast.next) {
17 | fast = fast.next.next;
18 | slow = slow.next;
19 |
20 | if (slow == fast) {
21 | return true;
22 | }
23 | }
24 | return false;
25 | }
26 |
27 | private class ListNode {
28 | int val;
29 | ListNode next;
30 |
31 | ListNode(int x) {
32 | val = x;
33 | next = null;
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution948.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc: 令牌放置
8 | * @date: 2019/02/12
9 | */
10 | public class Solution948 {
11 | public int bagOfTokensScore(int[] tokens, int P) {
12 | Arrays.sort(tokens);
13 |
14 | int ans = 0, i = 0, j = tokens.length - 1, points = 0;
15 | while (i <= j) {
16 | if (P >= tokens[i]) {
17 | P -= tokens[i];
18 | ++points;
19 | ++i;
20 |
21 | ans = Math.max(ans, points);
22 | } else if (0 < points) {
23 | --points;
24 | P += tokens[j];
25 | --j;
26 | } else {
27 | break;
28 | }
29 | }
30 | return ans;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution938.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二叉搜索树的范围和
6 | * @date: 2019/03/02
7 | */
8 | public class Solution938 {
9 |
10 | public int rangeSumBST(TreeNode root, int L, int R) {
11 | if (null == root) {
12 | return 0;
13 | }
14 |
15 | if (root.val < L) {
16 | return rangeSumBST(root.right, L, R);
17 | } else if (root.val > R) {
18 | return rangeSumBST(root.left, L, R);
19 | } else {
20 | return root.val + rangeSumBST(root.left, L, R) + rangeSumBST(root.right, L, R);
21 | }
22 | }
23 |
24 | public class TreeNode {
25 | int val;
26 | TreeNode left;
27 | TreeNode right;
28 |
29 | TreeNode(int x) {
30 | val = x;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution455.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc: 分发饼干
8 | * @date: 2018/08/18
9 | */
10 | public class Solution455 {
11 | public static void main(String[] args) {
12 | int[] g = {1, 2};
13 | int[] s = {1, 2, 3};
14 |
15 | Solution455 test = new Solution455();
16 | System.out.println(test.findContentChildren(g, s));
17 | }
18 |
19 | public int findContentChildren(int[] g, int[] s) {
20 | Arrays.sort(g);
21 | Arrays.sort(s);
22 |
23 | int gIndex = 0, sIndex = 0;
24 | while (gIndex < g.length && sIndex < s.length) {
25 | if (g[gIndex] <= s[sIndex]) {
26 | ++gIndex;
27 | }
28 | ++sIndex;
29 | }
30 | return gIndex;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main0901.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.HashMap;
4 | import java.util.Scanner;
5 |
6 | /**
7 | * 拼多多
8 | *
9 | * 求循环小数位置和循环体长度
10 | */
11 | public class Main0901 {
12 | public static void main(String[] args) {
13 | Scanner sc = new Scanner(System.in);
14 | int m = sc.nextInt();
15 | int n = sc.nextInt();
16 |
17 | HashMap map = new HashMap<>();
18 | int k = m % n;
19 | int count = 0;
20 | while (map.get(k) == null && k != 0) {
21 | map.put(k, count++);
22 | k *= 10;
23 | k %= n;
24 | }
25 | if (k == 0) {
26 | System.out.println(count + " " + 0);
27 | } else {
28 | System.out.println(map.get(k) + " " + (count - map.get(k)));
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution206.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/11/22
7 | */
8 | public class Solution206 {
9 |
10 | public ListNode reverseList(ListNode head) {
11 | if (null == head) {
12 | return head;
13 | }
14 |
15 | ListNode pre = null;
16 | ListNode cur = head;
17 | head = head.next;
18 |
19 | while (null != cur) {
20 | cur.next = pre;
21 |
22 | pre = cur;
23 | cur = head;
24 | if (null != head){
25 | head = head.next;
26 | }
27 | }
28 |
29 | return pre;
30 | }
31 |
32 |
33 | class ListNode {
34 | int val;
35 | ListNode next;
36 |
37 | ListNode(int x) {
38 | val = x;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/knapsack/Problem02.java:
--------------------------------------------------------------------------------
1 | package algorithm.knapsack;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 完全背包问题
6 | * @date: 2018/09/04
7 | */
8 | public class Problem02 {
9 | public static void main(String[] args) {
10 | int[] weights = {1, 2, 3, 4, 5};
11 | int[] values = {5, 1, 3, 2, 1};
12 |
13 | System.out.println(knapsack01(5, 5, weights, values));
14 | }
15 |
16 | public static int knapsack01(int numberOfGoods, int W, int[] weights, int[] values) {
17 | int[] dp = new int[numberOfGoods + 1];
18 |
19 | for (int i = 1; i <= numberOfGoods; ++i) {
20 | int w = weights[i - 1];
21 | int v = values[i - 1];
22 | for (int j = w; j <= W; ++j) {
23 | dp[j] = Math.max(dp[j], dp[j - w] + v);
24 | }
25 | }
26 | return dp[numberOfGoods];
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution123.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 买卖股票的最佳时机 III
6 | * @date: 2019/01/28
7 | */
8 | public class Solution123 {
9 |
10 | /**
11 | * buy first -> sell first -> buy second -> sell second
12 | *
13 | * @param prices
14 | * @return
15 | */
16 | public int maxProfit(int[] prices) {
17 | if (null == prices || 1 >= prices.length) {
18 | return 0;
19 | }
20 |
21 | int buy1 = Integer.MIN_VALUE, sell1 = 0;
22 | int buy2 = Integer.MIN_VALUE, sell2 = 0;
23 | for (int e : prices) {
24 | buy1 = Math.max(buy1, -e);
25 | sell1 = Math.max(sell1, buy1 + e);
26 | buy2 = Math.max(buy2, sell1 - e);
27 | sell2 = Math.max(sell2, buy2 + e);
28 | }
29 | return sell2;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution526.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 优美的排列
6 | * @date: 2019/02/16
7 | */
8 | public class Solution526 {
9 |
10 | int count = 0;
11 |
12 | public int countArrangement(int N) {
13 | if (0 >= N) {
14 | return 0;
15 | }
16 |
17 | dfs(N, 1, new boolean[N + 1]);
18 | return count;
19 | }
20 |
21 | public void dfs(int N, int pos, boolean[] hasVisited) {
22 | if (pos > N) {
23 | ++count;
24 | return;
25 | }
26 |
27 | for (int i = 1; i <= N; ++i) {
28 | if (!hasVisited[i] && (0 == i % pos || 0 == pos % i)) {
29 | hasVisited[i] = true;
30 | dfs(N, pos + 1, hasVisited);
31 | hasVisited[i] = false;
32 | }
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt07/EmptyExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt07;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/07/05
9 | */
10 | public class EmptyExceptionHandler {
11 |
12 | public static void main(String[] args) {
13 | ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
14 | System.out.println(mainGroup.getName());
15 | System.out.println(mainGroup.getParent());
16 | System.out.println(mainGroup.getParent().getParent());
17 |
18 | final Thread thread = new Thread(() -> {
19 | try {
20 | TimeUnit.SECONDS.sleep(2);
21 | } catch (InterruptedException e) {
22 | }
23 |
24 | System.out.println(1 / 0);
25 | }, "Test-Thread");
26 |
27 | thread.start();
28 |
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/design/command/Invoker.java:
--------------------------------------------------------------------------------
1 | package design.command;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/07/14
7 | */
8 | public class Invoker {
9 | private Command[] onCommands;
10 | private Command[] offCommands;
11 | private final int slotNum = 7;
12 |
13 | public Invoker() {
14 | this.onCommands = new Command[slotNum];
15 | this.offCommands = new Command[slotNum];
16 | }
17 |
18 | public void setOnCommand(Command command, int slot) {
19 | onCommands[slot] = command;
20 | }
21 |
22 | public void setOffCommand(Command command, int slot) {
23 | offCommands[slot] = command;
24 | }
25 |
26 | public void onButtonWasPushed(int slot) {
27 | onCommands[slot].execute();
28 | }
29 |
30 | public void offButtonWasPushed(int slot) {
31 | offCommands[slot].execute();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution322.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc: 零钱兑换
8 | * @date: 2018/08/23
9 | */
10 | public class Solution322 {
11 | public int coinChange(int[] coins, int amount) {
12 | if (null == coins || 0 >= coins.length || 0 > amount) {
13 | return 0;
14 | }
15 |
16 | Arrays.sort(coins);
17 | int[] dp = new int[amount + 1];
18 | // 最多用 amount 个 1元硬币,故此处初始化为 amount+1 用于判断是否能够凑齐
19 | Arrays.fill(dp, amount + 1);
20 | dp[0] = 0;
21 |
22 | for (int i = 1; i <= amount; ++i) {
23 | for (int j = 0; j < coins.length && coins[j] <= i; ++j) {
24 | dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
25 | }
26 | }
27 | return (dp[amount] > amount) ? -1 : dp[amount];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution621.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 任务调度器
6 | * @date: 2019/01/21
7 | */
8 | public class Solution621 {
9 |
10 | public int leastInterval(char[] tasks, int n) {
11 | int[] dict = new int[26];
12 | for (char c : tasks) {
13 | ++dict[c - 'A'];
14 | }
15 |
16 | // 出现次数最多的任务,其总次数
17 | int maxNumber = 0;
18 | // 总次数最大,任务数量
19 | int sameCnt = 1;
20 | for (int e : dict) {
21 | if (maxNumber < e) {
22 | maxNumber = e;
23 | sameCnt = 1;
24 | } else if (maxNumber == e) {
25 | ++sameCnt;
26 | }
27 | }
28 |
29 | int space = (n + 1) * (maxNumber - 1) + sameCnt;
30 | return space < tasks.length ? tasks.length : space;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main090601.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/09/06
9 | */
10 | public class Main090601 {
11 | public static void main(String args[]) {
12 | Scanner scanner = new Scanner(System.in);
13 | int n = Integer.parseInt(scanner.nextLine());
14 |
15 | int[] from = new int[n + 1];
16 | int[] to = new int[n + 1];
17 |
18 | for (int i = 1; i < n; ++i) {
19 | String[] temp = scanner.nextLine().split("\\s+");
20 | int x = Integer.parseInt(temp[0]);
21 | int y = Integer.parseInt(temp[1]);
22 | from[i] = x;
23 | to[i] = y;
24 | }
25 |
26 | if (n <= 4) {
27 | System.out.println(n);
28 | } else {
29 | System.out.println(n + 3);
30 | }
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt02/ThreadConstruction.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt02;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/06/28
7 | */
8 | public class ThreadConstruction {
9 |
10 | public static void main(String[] args) {
11 | System.out.println(args.length);
12 | System.out.println(args);
13 |
14 |
15 | Thread t1 = new Thread("t1");
16 |
17 | ThreadGroup group = new ThreadGroup("TestGroup");
18 | Thread t2 = new Thread(group, "t2");
19 |
20 | ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
21 |
22 | System.out.println("Main thread belong to " + mainGroup.getName() + " group.");
23 | System.out.println("t1 thread belong to " + t1.getThreadGroup().getName() + " group.");
24 | System.out.println("t2 thread belong to " + t2.getThreadGroup().getName() + " group.");
25 |
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt05/EventClient.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt05;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/07/03
9 | */
10 | public class EventClient {
11 |
12 | public static void main(String[] args) {
13 | final EventQueue eventQueue = new EventQueue();
14 | new Thread(() -> {
15 | while (true) {
16 | eventQueue.offer(new EventQueue.Event());
17 | }
18 | }, "Producer").start();
19 |
20 | new Thread(() -> {
21 | while (true) {
22 | eventQueue.take();
23 | try {
24 | TimeUnit.SECONDS.sleep(10);
25 | } catch (InterruptedException e) {
26 | e.printStackTrace();
27 | }
28 | }
29 | }, "Consumer").start();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution038.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author mayuan
5 | * @desc
6 | * @date 2018/02/09
7 | */
8 | public class Solution038 {
9 |
10 | public String countAndSay(int n) {
11 | String str = "1";
12 | while (--n > 0) {
13 | int times = 1;
14 | StringBuilder sb = new StringBuilder();
15 | char[] chars = str.toCharArray();
16 | int len = chars.length;
17 | for (int j = 1; j < len; j++) {
18 | if (chars[j - 1] == chars[j]) {
19 | times++;
20 | } else {
21 | sb.append(times).append(chars[j - 1]);
22 | times = 1;
23 | }
24 | }
25 | str = sb.append(times).append(chars[len - 1]).toString();
26 | }
27 | return str;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution024.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/07/16
7 | */
8 | public class Solution024 {
9 | public ListNode swapPairs(ListNode head) {
10 | if (null == head || null == head.next) {
11 | return head;
12 | }
13 |
14 | ListNode temp = new ListNode(-1);
15 | temp.next = head;
16 | ListNode p = temp;
17 |
18 | while (null != p.next && null != p.next.next) {
19 | ListNode t = p.next;
20 | p.next = t.next;
21 | t.next = p.next.next;
22 | p.next.next = t;
23 | p = t;
24 | }
25 | return temp.next;
26 | }
27 |
28 | private class ListNode {
29 | int val;
30 | ListNode next;
31 |
32 | ListNode(int x) {
33 | val = x;
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution063.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 不同路径 II
6 | * @date: 2019/02/17
7 | */
8 | public class Solution063 {
9 | public int uniquePathsWithObstacles(int[][] obstacleGrid) {
10 | if (null == obstacleGrid || 0 >= obstacleGrid.length) {
11 | return 0;
12 | }
13 |
14 | // 列数
15 | int m = obstacleGrid[0].length;
16 | // dp[i][j]代表走到第(i,j)个位置共多少种路径
17 | int[] dp = new int[m];
18 | dp[0] = 1;
19 |
20 | for (int[] row : obstacleGrid) {
21 | for (int j = 0; j < m; ++j) {
22 | if (1 == row[j]) {
23 | dp[j] = 0;
24 | } else if (0 < j) {
25 | dp[j] = dp[j] + dp[j - 1];
26 | }
27 | }
28 | }
29 |
30 | return dp[m - 1];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt03/ThreadInterrupted3.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt03;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/06/30
9 | */
10 | public class ThreadInterrupted3 {
11 | public static void main(String[] args) throws InterruptedException {
12 | Thread thread = new Thread() {
13 | @Override
14 | public void run() {
15 | while (true) {
16 | boolean fl = Thread.interrupted();
17 | if (fl){
18 | System.out.print("**************");
19 | }
20 | System.out.println(fl);
21 | }
22 | }
23 | };
24 | thread.setDaemon(true);
25 | thread.start();
26 |
27 | TimeUnit.MILLISECONDS.sleep(2);
28 | thread.interrupt();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution274.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: H指数
6 | * @date: 2019/01/14
7 | */
8 | public class Solution274 {
9 |
10 | public int hIndex(int[] citations) {
11 | if (null == citations || 0 >= citations.length) {
12 | return 0;
13 | }
14 |
15 | int N = citations.length;
16 | int[] buckets = new int[citations.length + 1];
17 | for (int i = 0; i < N; ++i) {
18 | if (citations[i] >= N) {
19 | ++buckets[N];
20 | } else {
21 | ++buckets[citations[i]];
22 | }
23 | }
24 |
25 | int cnt = 0;
26 | for (int i = N; i >= 0; --i) {
27 | cnt += buckets[i];
28 | if (i <= cnt) {
29 | return i;
30 | }
31 | }
32 | return 0;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution633.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/17
7 | */
8 | public class Solution633 {
9 | public static void main(String[] args) {
10 | Solution633 test = new Solution633();
11 |
12 | System.out.println(test.judgeSquareSum(100000));
13 | }
14 |
15 | public boolean judgeSquareSum(int c) {
16 | if (0 > c) {
17 | return false;
18 | }
19 |
20 | int left = 0;
21 | int right = (int) Math.sqrt(c);
22 | while (left <= right) {
23 | int temp = left * left + right * right;
24 | if (temp < c) {
25 | ++left;
26 | } else if (temp > c) {
27 | --right;
28 | } else {
29 | return true;
30 | }
31 | }
32 | return false;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution881.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc: 救生艇
8 | * @date: 2019/01/12
9 | */
10 | public class Solution881 {
11 |
12 | /**
13 | * 先对数组进行排序
14 | * i指针指向开始(体重轻),j指针指向末尾(体重重)
15 | * 重的人肯定能坐上船,因此j指针每次循环均能够减一.
16 | * 轻的人只有和重的人两个体重和不超过限制才能坐上船.
17 | *
18 | * @param people
19 | * @param limit
20 | * @return
21 | */
22 | public int numRescueBoats(int[] people, int limit) {
23 | if (null == people || 0 >= people.length) {
24 | return 0;
25 | }
26 |
27 | Arrays.sort(people);
28 | int ans = 0;
29 | for (int i = 0, j = people.length - 1; i <= j; --j, ++ans) {
30 | if (people[i] + people[j] <= limit) {
31 | ++i;
32 | }
33 | }
34 | return ans;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution053.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最大子序和
6 | * @date: 2018/08/17
7 | */
8 | public class Solution053 {
9 | public static void main(String[] args) {
10 | int[] nums = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
11 |
12 | Solution053 test = new Solution053();
13 | System.out.println(test.maxSubArray(nums));
14 | }
15 |
16 | public int maxSubArray(int[] nums) {
17 | if (null == nums || 0 >= nums.length) {
18 | return 0;
19 | }
20 |
21 | // dp[i]代表以第i个位置结尾,最大子序和
22 | int[] dp = new int[nums.length];
23 | dp[0] = nums[0];
24 | int ans = dp[0];
25 |
26 | for (int i = 1; i < nums.length; ++i) {
27 | dp[i] = Math.max(nums[i] + dp[i - 1], nums[i]);
28 | ans = Math.max(ans, dp[i]);
29 | }
30 | return ans;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution137.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 只出现一次的数字 II
6 | * @date: 2019/01/30
7 | */
8 | public class Solution137 {
9 |
10 | public static void main(String[] args) {
11 | int[] nums = {2, 2, 3, 2};
12 | System.out.println(new Solution137().singleNumber(nums));
13 | }
14 |
15 | public int singleNumber(int[] nums) {
16 | if (null == nums || 1 > nums.length) {
17 | return 0;
18 | }
19 |
20 | int ans = 0;
21 | for (int i = 0; i < 32; ++i) {
22 | int sum = 0;
23 | for (int e : nums) {
24 | if (1 == ((e >>> i) & 1)) {
25 | ++sum;
26 | }
27 | }
28 |
29 | if (0 != sum % 3) {
30 | ans |= 1 << i;
31 | }
32 | }
33 | return ans;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution089.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 格雷编码
9 | * @date: 2018/08/12
10 | */
11 | public class Solution089 {
12 | public static void main(String[] args) {
13 | Solution089 test = new Solution089();
14 | List ans = test.grayCode(2);
15 |
16 | ans.forEach(System.out::println);
17 | }
18 |
19 | /**
20 | * 此题定义 格雷编码序列必须以 0 开头
21 | * 给定编码总位数为 n 的格雷编码序列,其长度为 2^n。当 n = 0 时,长度为 2^0 = 1。
22 | * 因此,当 n = 0 时,其格雷编码序列为 [0]。
23 | *
24 | * @param n
25 | * @return
26 | */
27 | public List grayCode(int n) {
28 | List answer = new LinkedList<>();
29 | for (int i = 0; i < Math.pow(2, n); i++) {
30 | answer.add(i ^ (i >> 1));
31 | }
32 | return answer;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/note/LRU.java:
--------------------------------------------------------------------------------
1 | package algorithm.note;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: LRU算法的实现
9 | * @date: 2018/09/14
10 | */
11 | public class LRU {
12 |
13 | private static final float loadFactor = 0.75F;
14 | private final int capacity;
15 |
16 | private LinkedHashMap map;
17 |
18 | public LRU(int size) {
19 | this.capacity = size;
20 | int cap = (int) Math.ceil(size / loadFactor) + 1;
21 |
22 | map = new LinkedHashMap(cap, loadFactor, true) {
23 | @Override
24 | protected boolean removeEldestEntry(Map.Entry entry) {
25 | return size() > capacity;
26 | }
27 | };
28 | }
29 |
30 | public K get(K key) {
31 | return map.get(key);
32 | }
33 |
34 | public void put(K key) {
35 | map.put(key, key);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution062.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc: 不同路径
8 | * @date: 2018/08/22
9 | */
10 | public class Solution062 {
11 | public static void main(String[] args) {
12 | Solution062 test = new Solution062();
13 |
14 | System.out.println(test.uniquePaths(7, 3));
15 | System.out.println(test.uniquePaths(3, 2));
16 | }
17 |
18 | public int uniquePaths(int m, int n) {
19 | // m 指的是列数
20 | int[] dp = new int[m];
21 | // 初始状态: 第一行的位置(即到达该位置仅有1种走法)
22 | Arrays.fill(dp, 1);
23 | // 每行的第一列的位置(到达该位置也仅有1种走法)
24 | for (int i = 1; i < n; ++i) {
25 | for (int j = 0; j < m; ++j) {
26 | // 到达该位置的方法数为: 从上方走过来的走法数目 + 从左侧方向走过来的走法数目
27 | dp[j] = dp[j] + dp[j - 1];
28 | }
29 | }
30 | return dp[m - 1];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution122.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 买卖股票的最佳时机 II
6 | * @date: 2018/08/19
7 | */
8 | public class Solution122 {
9 |
10 | /**
11 | * 由于可以多次买卖股票:
12 | * 对于 [a, b, c, d],如果有 a <= b <= c <= d ,那么最大收益为 d - a。
13 | * 而 d - a = (d - c) + (c - b) + (b - a) ,因此当访问到一个 prices[i] 且 prices[i] - prices[i-1] > 0,
14 | * 那么就把 prices[i] - prices[i-1] 添加到收益中,从而在局部最优的情况下也保证全局最优。
15 | *
16 | * @param prices
17 | * @return
18 | */
19 | public int maxProfit(int[] prices) {
20 | if (null == prices || 0 >= prices.length) {
21 | return 0;
22 | }
23 |
24 | int profit = 0;
25 | for (int i = 1; i < prices.length; ++i) {
26 | if (prices[i - 1] < prices[i]) {
27 | profit += (prices[i] - prices[i - 1]);
28 | }
29 | }
30 | return profit;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution283.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 移动零
6 | * @date: 2019/01/04
7 | */
8 | public class Solution283 {
9 |
10 | public static void main(String[] args) {
11 | int[] numbers = {0, 1, 0, 3, 12};
12 | new Solution283().moveZeroes(numbers);
13 |
14 | for (int i = 0; i < numbers.length; ++i) {
15 | System.out.print(numbers[i]);
16 | System.out.print(" ");
17 | }
18 | }
19 |
20 | public void moveZeroes(int[] nums) {
21 | if (null == nums || 1 >= nums.length) {
22 | return;
23 | }
24 |
25 | int i = 0, j = 0;
26 | for (; j < nums.length; ++j) {
27 | if (0 != nums[j]) {
28 | nums[i++] = nums[j];
29 | }
30 | }
31 |
32 | for (; i < nums.length; ++i) {
33 | nums[i] = 0;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution349.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | /**
7 | * @author Administrator
8 | * @desc 两个数组的交集
9 | * @create 2019/01/08
10 | */
11 | public class Solution349 {
12 |
13 | public int[] intersection(int[] nums1, int[] nums2) {
14 | Set set = new HashSet<>(nums1.length);
15 | Set intersect = new HashSet<>(nums2.length);
16 |
17 | for (int i = 0; i < nums1.length; ++i) {
18 | set.add(nums1[i]);
19 | }
20 | for (int i = 0; i < nums2.length; ++i) {
21 | if (set.contains(nums2[i])) {
22 | intersect.add(nums2[i]);
23 | }
24 | }
25 |
26 | int[] ans = new int[intersect.size()];
27 | int i = 0;
28 | for (Integer n : intersect) {
29 | ans[i++] = n;
30 | }
31 | return ans;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution513.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 找树左下角的值
6 | * @date: 2019/03/15
7 | */
8 | public class Solution513 {
9 | int ans = 0;
10 | int curDepth = 0;
11 |
12 | public int findBottomLeftValue(TreeNode root) {
13 | dfs(root, 1);
14 | return ans;
15 | }
16 |
17 | public void dfs(TreeNode node, int depth) {
18 | if (curDepth < depth) {
19 | ans = node.val;
20 | curDepth = depth;
21 | }
22 |
23 | if (null != node.left) {
24 | dfs(node.left, depth + 1);
25 | }
26 | if (null != node.right) {
27 | dfs(node.right, depth + 1);
28 | }
29 | }
30 |
31 | public class TreeNode {
32 | int val;
33 | TreeNode left;
34 | TreeNode right;
35 |
36 | TreeNode(int x) {
37 | val = x;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution783.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二叉搜索树结点最小距离
6 | * @date: 2019/03/02
7 | */
8 | public class Solution783 {
9 |
10 | TreeNode pre;
11 | int mn = Integer.MAX_VALUE;
12 |
13 | public int minDiffInBST(TreeNode root) {
14 | inOrder(root);
15 | return mn;
16 | }
17 |
18 | public void inOrder(TreeNode node) {
19 | if (null == node) {
20 | return;
21 | }
22 |
23 | inOrder(node.left);
24 | if (null != pre) {
25 | mn = Math.min(mn, node.val - pre.val);
26 | }
27 | // 遍历右子树时,pre引用需要更新为node
28 | pre = node;
29 | inOrder(node.right);
30 | }
31 |
32 | public class TreeNode {
33 | int val;
34 | TreeNode left;
35 | TreeNode right;
36 |
37 | TreeNode(int x) {
38 | val = x;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/str/Problem08.java:
--------------------------------------------------------------------------------
1 | package algorithm.str;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 翻转字符串里的单词
6 | * @date: 2018/09/08
7 | */
8 | public class Problem08 {
9 |
10 | public static void main(String[] args) {
11 | Problem08 test = new Problem08();
12 |
13 | String ans = test.reverseWords(" 1");
14 | System.out.println(ans);
15 | }
16 |
17 | public String reverseWords(String s) {
18 | if (null == s) {
19 | return s;
20 | }
21 | if (s.trim().length() == 0) {
22 | return s.trim();
23 | }
24 |
25 | String[] temp = s.trim().split("\\s+");
26 |
27 | StringBuilder stringBuilder = new StringBuilder();
28 | for (int i = temp.length - 1; i > 0; --i) {
29 | stringBuilder.append(temp[i] + " ");
30 | }
31 | stringBuilder.append(temp[0]);
32 | return stringBuilder.toString();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution002.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 时间复杂度: O(n)
6 | * 空间复杂度: O(n)
7 | * @date: 2018/11/20
8 | */
9 | public class Solution002 {
10 |
11 | public static void main(String[] args) {
12 | final String input = "I am a student.";
13 |
14 | System.out.println(reverseSentence(input));
15 | }
16 |
17 | public static String reverseSentence(String text) {
18 | if (null == text || 0 >= text.length()) {
19 | return null;
20 | }
21 |
22 | String[] tmp = text.split("\\s+");
23 | StringBuilder stringBuilder = new StringBuilder();
24 | for (int i = tmp.length - 1; i >= 0; --i) {
25 | stringBuilder.append(tmp[i]);
26 | if (0 != i) {
27 | stringBuilder.append(" ");
28 | }
29 | }
30 |
31 | return stringBuilder.toString();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution144a.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/17
7 | */
8 | public class Solution144a {
9 | public static void main(String[] args) {
10 |
11 | }
12 |
13 | public boolean hasCycle(ListNode head) {
14 | if (null == head) {
15 | return false;
16 | }
17 |
18 | ListNode slow = head;
19 | ListNode fast = head.next;
20 |
21 | while (null != fast && null != fast.next && null != slow) {
22 | if (slow == fast) {
23 | return true;
24 | }
25 |
26 | slow = slow.next;
27 | fast = fast.next.next;
28 | }
29 | return false;
30 | }
31 |
32 | class ListNode {
33 | int val;
34 | ListNode next;
35 |
36 | ListNode(int x) {
37 | val = x;
38 | next = null;
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution530.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二叉搜索树的最小绝对差
6 | * @date: 2019/03/02
7 | */
8 | public class Solution530 {
9 |
10 | TreeNode pre;
11 | int mn = Integer.MAX_VALUE;
12 |
13 | public int getMinimumDifference(TreeNode root) {
14 | inOrder(root);
15 | return mn;
16 | }
17 |
18 | public void inOrder(TreeNode node) {
19 | if (null == node) {
20 | return;
21 | }
22 |
23 | inOrder(node.left);
24 | if (null != pre) {
25 | mn = Math.min(mn, node.val - pre.val);
26 | }
27 | // 遍历右子树时,pre引用需要更新为node
28 | pre = node;
29 | inOrder(node.right);
30 | }
31 |
32 | public class TreeNode {
33 | int val;
34 | TreeNode left;
35 | TreeNode right;
36 |
37 | TreeNode(int x) {
38 | val = x;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution744.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/19
7 | */
8 | public class Solution744 {
9 | public static void main(String[] args) {
10 | char[] array = {'c', 'f', 'j'};
11 |
12 | Solution744 test = new Solution744();
13 | System.out.println(test.nextGreatestLetter(array, 'd'));
14 | }
15 |
16 | public char nextGreatestLetter(char[] letters, char target) {
17 | int left = 0, right = letters.length - 1;
18 | while (left <= right) {
19 | int mid = left + (right - left) / 2;
20 | if (letters[mid] <= target) {
21 | left = mid + 1;
22 | } else {
23 | right = mid - 1;
24 | }
25 | }
26 | // 找出 letters 中大于 target 的最小字符,如果找不到就返回第 1 个字符。
27 | return (left < letters.length) ? letters[left] : letters[0];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution404.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 左叶子之和
6 | * @date: 2019/03/10
7 | */
8 | public class Solution404 {
9 | public int sumOfLeftLeaves(TreeNode root) {
10 | if (null == root){
11 | return 0;
12 | }
13 |
14 | return dfs(root.left, true) + dfs(root.right, false);
15 | }
16 |
17 | private int dfs(TreeNode node, boolean isLeft) {
18 | if (null == node) {
19 | return 0;
20 | }
21 |
22 | if (null == node.left && null == node.right && isLeft) {
23 | return node.val;
24 | } else {
25 | return dfs(node.left, true) + dfs(node.right, false);
26 | }
27 | }
28 |
29 | public class TreeNode {
30 | int val;
31 | TreeNode left;
32 | TreeNode right;
33 |
34 | TreeNode(int x) {
35 | val = x;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution955.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 删列造序 II
6 | * @date: 2019/02/12
7 | */
8 | public class Solution955 {
9 | public int minDeletionSize(String[] A) {
10 | int ans = 0, n = A.length, m = A[0].length(), i, j;
11 | boolean[] sorted = new boolean[n - 1];
12 |
13 | for (j = 0; j < m; ++j) {
14 | for (i = 0; i < n - 1; ++i) {
15 | if (!sorted[i] && A[i].charAt(j) > A[i + 1].charAt(j)) {
16 | ++ans;
17 | break;
18 | }
19 | }
20 |
21 | if (i < n - 1) {
22 | continue;
23 | }
24 | for (i = 0; i < n - 1; ++i) {
25 | if (A[i].charAt(j) < A[i + 1].charAt(j)) {
26 | sorted[i] = true;
27 | }
28 | }
29 | }
30 | return ans;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution152.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 乘积最大子序列
6 | * @date: 2019/02/17
7 | */
8 | public class Solution152 {
9 | public int maxProduct(int[] nums) {
10 | if (null == nums || 0 >= nums.length) {
11 | return 0;
12 | }
13 |
14 | int ans = nums[0];
15 | for (int i = 1, mx = nums[0], mn = nums[0]; i < nums.length; ++i) {
16 | // 以当前位置结尾,乘积最大的连续子序列有以下几种情况:
17 | // 1. 当前元素为正数,从前一状态挑选最大值转移过来
18 | // 2. 当前元素为负数,从前一状态挑选最小值转移过来(负负得正)
19 | // 3. 前一状态为0, 从前一状态或当前元素选择最大值
20 | int a = mx * nums[i];
21 | int b = mn * nums[i];
22 | mx = Math.max(Math.max(a, b), nums[i]);
23 | mn = Math.min(Math.min(a, b), nums[i]);
24 | if (mx > ans) {
25 | ans = mx;
26 | }
27 | }
28 |
29 | return ans;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/alg4/Solution004.java:
--------------------------------------------------------------------------------
1 | package algorithm.alg4;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/10/28
7 | */
8 | public class Solution004 {
9 |
10 | public static void main(String[] args) {
11 | System.out.println("abcd 是回文字符串吗? " + isPalindrome("abcd"));
12 | System.out.println("abcdcba 是回文字符串吗? " + isPalindrome("abcdcba"));
13 | System.out.println("aaaa 是回文字符串吗? " + isPalindrome("aaaa"));
14 | }
15 |
16 | /**
17 | * 判断字符串是否为回文字符串
18 | *
19 | * @param str
20 | * @return
21 | */
22 | public static boolean isPalindrome(String str) {
23 | if (null == str || 0 == str.length()) {
24 | return false;
25 | }
26 |
27 | for (int i = 0; i < str.length() / 2; ++i) {
28 | if (str.charAt(i) != str.charAt(str.length() - 1 - i)) {
29 | return false;
30 | }
31 | }
32 | return true;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution264.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 丑数 II
6 | * @date: 2019/02/22
7 | */
8 | public class Solution264 {
9 | public int nthUglyNumber(int n) {
10 | // dp[i]代表第i个丑数
11 | int[] dp = new int[n + 1];
12 | // 第一个丑数为1
13 | dp[1] = 1;
14 |
15 | int index2 = 1, index3 = 1, index5 = 1;
16 | int factor2 = 2, factor3 = 3, factor5 = 5;
17 | for (int i = 2; i <= n; ++i) {
18 | int mn = Math.min(Math.min(factor2, factor3), factor5);
19 | dp[i] = mn;
20 |
21 | if (mn == factor2) {
22 | factor2 = 2 * dp[++index2];
23 | }
24 | if (mn == factor3) {
25 | factor3 = 3 * dp[++index3];
26 | }
27 | if (mn == factor5) {
28 | factor5 = 5 * dp[++index5];
29 | }
30 | }
31 | return dp[n];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution101.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 对称二叉树
6 | * @date: 2019/02/26
7 | */
8 | public class Solution101 {
9 |
10 | public boolean isSymmetric(TreeNode root) {
11 | if (null == root) {
12 | return true;
13 | }
14 |
15 | return isSymmetric(root.left, root.right);
16 | }
17 |
18 | public boolean isSymmetric(TreeNode left, TreeNode right) {
19 | if (null == left || null == right) {
20 | return left == right;
21 | }
22 |
23 | if (left.val != right.val){
24 | return false;
25 | }
26 |
27 | return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
28 | }
29 |
30 | public class TreeNode {
31 | int val;
32 | TreeNode left;
33 | TreeNode right;
34 |
35 | TreeNode(int x) {
36 | val = x;
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution738.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 单调递增的数字
6 | * @date: 2019/01/22
7 | */
8 | public class Solution738 {
9 |
10 | public static void main(String[] args) {
11 | final int n = 332;
12 |
13 | System.out.println(new Solution738().monotoneIncreasingDigits(n));
14 | }
15 |
16 | public int monotoneIncreasingDigits(int N) {
17 | char[] number = String.valueOf(N).toCharArray();
18 |
19 | // 必须从后向前推导,才能确保最前面几个数字是递增的
20 | int mark = number.length;
21 | for (int i = number.length - 1; i > 0; --i) {
22 | if (number[i] < number[i - 1]) {
23 | mark = i - 1;
24 | --number[mark];
25 | }
26 | }
27 |
28 | for (int i = mark + 1; i < number.length; ++i) {
29 | number[i] = '9';
30 | }
31 |
32 | return Integer.parseInt(new String(number));
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/str/Problem07.java:
--------------------------------------------------------------------------------
1 | package algorithm.str;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 第一个只出现一次的字符
9 | * @date: 2018/09/08
10 | */
11 | public class Problem07 {
12 | public static void main(String[] args) {
13 | String str = "abcabb";
14 |
15 | int ans = FirstNotRepeatingChar(str);
16 | System.out.println((char)ans);
17 | }
18 |
19 | public static int FirstNotRepeatingChar(String str) {
20 | if (null == str || str.length() < 1) {
21 | return -1;
22 | }
23 |
24 | Map map = new HashMap<>(128);
25 | for (char c : str.toCharArray()) {
26 | map.put(c, map.getOrDefault(c, 0) + 1);
27 | }
28 |
29 | for (char c : str.toCharArray()) {
30 | if (1 == map.getOrDefault(c, 0)) {
31 | return c;
32 | }
33 | }
34 | return -1;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution086.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 分隔链表
6 | * @date: 2019/01/03
7 | */
8 | public class Solution086 {
9 |
10 | public ListNode partition(ListNode head, int x) {
11 | ListNode node1 = new ListNode(0);
12 | ListNode node2 = new ListNode(0);
13 | ListNode p1 = node1, p2 = node2;
14 |
15 | while (null != head) {
16 | if (x > head.val) {
17 | p1.next = head;
18 | p1 = p1.next;
19 | } else {
20 | p2.next = head;
21 | p2 = p2.next;
22 | }
23 | head = head.next;
24 | }
25 |
26 | p2.next = null;
27 | p1.next = node2.next;
28 | return node1.next;
29 | }
30 |
31 | private class ListNode {
32 | int val;
33 | ListNode next;
34 |
35 | ListNode(int x) {
36 | val = x;
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution209.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 长度最小的子数组
6 | * @date: 2019/01/04
7 | */
8 | public class Solution209 {
9 |
10 | public int minSubArrayLen(int s, int[] nums) {
11 | if (0 > s || null == nums || 1 > nums.length) {
12 | return 0;
13 | }
14 |
15 | int i = 0, j = -1;
16 | int sum = 0;
17 | int len = nums.length + 1;
18 | while (i < nums.length) {
19 | if (j < nums.length - 1 && sum < s) {
20 | ++j;
21 | sum += nums[j];
22 | } else {
23 | sum -= nums[i];
24 | ++i;
25 | }
26 |
27 | if (sum >= s) {
28 | len = len < j - i + 1 ? len : j - i + 1;
29 | }
30 | }
31 | if (len == nums.length + 1) {
32 | return 0;
33 | } else {
34 | return len;
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution020.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 出现次数超过一半的数
6 | * 时间复杂度: O(n)
7 | * 空间复杂度: O(1)
8 | * @date:
9 | */
10 | public class Solution020 {
11 |
12 | public static void main(String[] args) {
13 | int[] array = {3, 1, 2, 3, 3, 0, 3};
14 |
15 | System.out.println(findNumber(array));
16 | }
17 |
18 | public static int findNumber(int[] array) {
19 | if (null == array || 0 >= array.length) {
20 | return -1;
21 | }
22 |
23 | int number = array[0];
24 | int count = 1;
25 | for (int i = 1; i < array.length; ++i) {
26 | if (array[i] == number) {
27 | ++count;
28 | } else {
29 | if (1 == count) {
30 | number = array[i];
31 | } else {
32 | --count;
33 | }
34 | }
35 | }
36 | return number;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution474.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/23
7 | */
8 | public class Solution474 {
9 | public int findMaxForm(String[] strs, int m, int n) {
10 | if (strs == null || strs.length == 0) {
11 | return 0;
12 | }
13 | int[][] dp = new int[m + 1][n + 1];
14 | // 每个字符串只能用一次
15 | for (String s : strs) {
16 | int zeros = 0, ones = 0;
17 | for (char c : s.toCharArray()) {
18 | if ('0' == c) {
19 | ++zeros;
20 | } else {
21 | ++ones;
22 | }
23 | }
24 |
25 | for (int i = m; i >= zeros; --i) {
26 | for (int j = n; j >= ones; --j) {
27 | dp[i][j] = Math.max(dp[i][j], dp[i - zeros][j - ones] + 1);
28 | }
29 | }
30 | }
31 | return dp[m][n];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution304.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二维区域和检索 - 矩阵不可变
6 | * @date: 2019/02/23
7 | */
8 | public class Solution304 {
9 | /**
10 | * dp[i][j] 表示从第(1,1)到第(i,j)范围的和,即从左上角到该位置范围的和
11 | */
12 | private int[][] dp;
13 |
14 | public Solution304(int[][] matrix) {
15 | if (null == matrix || 0 >= matrix.length || 0 >= matrix[0].length) {
16 | return;
17 | }
18 |
19 | int m = matrix.length;
20 | int n = matrix[0].length;
21 | dp = new int[m+1][n+1];
22 | for (int i = 1; i <= m; ++i) {
23 | for (int j = 1; j <= n; ++j) {
24 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + matrix[i - 1][j - 1];
25 | }
26 | }
27 | }
28 |
29 | public int sumRegion(int row1, int col1, int row2, int col2) {
30 | return dp[row2 + 1][col2 + 1] - dp[row2 + 1][col1] - dp[row1][col2 + 1] + dp[row1][col1];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution921.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2019/02/09
7 | */
8 | public class Solution921 {
9 |
10 | public static void main(String[] args) {
11 | String str1 = "()))((";
12 |
13 | Solution921 solution921 = new Solution921();
14 | System.out.println(solution921.minAddToMakeValid(str1));
15 | }
16 |
17 | public int minAddToMakeValid(String S) {
18 | if (null == S || 1 > S.length()) {
19 | return 0;
20 | }
21 |
22 | int left = 0, right = 0;
23 | for (int i = 0; i < S.length(); ++i) {
24 | char c = S.charAt(i);
25 | if ('(' == c) {
26 | ++left;
27 | } else {
28 | if (0 < left) {
29 | --left;
30 | } else {
31 | ++right;
32 | }
33 | }
34 | }
35 |
36 | return left + right;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution221.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最大正方形
6 | * @date: 2019/02/21
7 | */
8 | public class Solution221 {
9 | public int maximalSquare(char[][] matrix) {
10 | if (null == matrix || 0 >= matrix.length) {
11 | return 0;
12 | }
13 |
14 | int m = matrix.length, n = matrix[0].length;
15 | // dp[i][j]表示:以第(i,j)个元素为正方形右下角元素时,最大的边长.
16 | int[][] dp = new int[m + 1][n + 1];
17 | int ans = 0;
18 | for (int i = 1; i <= m; ++i) {
19 | for (int j = 1; j <= n; ++j) {
20 | // 如果当前位置为1
21 | if ('1' == matrix[i - 1][j - 1]) {
22 | dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j - 1]), dp[i - 1][j]) + 1;
23 | if (dp[i][j] > ans) {
24 | ans = dp[i][j];
25 | }
26 | }
27 | }
28 | }
29 | return ans * ans;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution129.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 求根到叶子节点数字之和
6 | * @date: 2019/03/09
7 | */
8 | public class Solution129 {
9 |
10 | public int sumNumbers(TreeNode root) {
11 | if (null == root) {
12 | return 0;
13 | }
14 |
15 | return dfs(root, 0);
16 | }
17 |
18 | public int dfs(TreeNode node, int sum) {
19 | if (null == node) {
20 | return 0;
21 | }
22 |
23 | int curNumber = sum * 10 + node.val;
24 | // 当前节点为叶子节点
25 | if (null == node.left && null == node.right) {
26 | return curNumber;
27 | } else {
28 | // 非叶子节点
29 | return dfs(node.left, curNumber) + dfs(node.right, curNumber);
30 | }
31 | }
32 |
33 | public class TreeNode {
34 | int val;
35 | TreeNode left;
36 | TreeNode right;
37 |
38 | TreeNode(int x) {
39 | val = x;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution260.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 只出现一次的数字 III
6 | * @date: 2019/01/30
7 | */
8 | public class Solution260 {
9 |
10 | public static void main(String[] args) {
11 | int[] nums = {2, 1, 2, 3, 4, 1};
12 |
13 | for (int e : new Solution260().singleNumber(nums)) {
14 | System.out.print(e + " ");
15 | }
16 | }
17 |
18 | public int[] singleNumber(int[] nums) {
19 | int[] ans = new int[2];
20 | if (null == nums || 0 >= nums.length) {
21 | return ans;
22 | }
23 |
24 | int diff = 0;
25 | for (int e : nums) {
26 | diff ^= e;
27 | }
28 |
29 | // 取最右侧1位的1
30 | diff &= -diff;
31 |
32 | for (int e : nums) {
33 | if (0 == (e & diff)) {
34 | ans[0] ^= e;
35 | } else {
36 | ans[1] ^= e;
37 | }
38 | }
39 | return ans;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution650.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/24
7 | */
8 | public class Solution650 {
9 | public static void main(String[] args) {
10 | Solution650 test = new Solution650();
11 |
12 | System.out.println(test.minSteps(6));
13 | }
14 |
15 | public int minSteps(int n) {
16 | // 得到长度为n 的字符串的最小操作:
17 | // 1.直接将字符'A'复制 1 次,然后粘贴 n-1 次,共n次操作
18 | // 2.n可以被一个比它自己小的数j整除(长度为n的字符串可以由多个长度为j的字符串组成),则可以复制 j 个字符串一次,然后粘贴 i/j - 1 次,共 i/j + dp[j]次
19 | int[] dp = new int[n + 1];
20 | dp[1] = 0;
21 |
22 | for (int i = 2; i <= n; ++i) {
23 | dp[i] = i;
24 | for (int j = 1; j < i; ++j) {
25 | // 最终得到字符串的大小只可能与当前存在的字符串有 i%j == 0的关系,否则无法得到.
26 | if (0 == i % j) {
27 | dp[i] = Math.min(dp[i], dp[j] + i / j);
28 | }
29 | }
30 | }
31 | return dp[n];
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt03/FlagThreadExit.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt03;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/07/01
9 | */
10 | public class FlagThreadExit {
11 |
12 | public static void main(String[] args) throws InterruptedException {
13 | MyTask t = new MyTask();
14 | t.start();
15 |
16 | TimeUnit.SECONDS.sleep(5);
17 | System.out.println("System will be shutdown.");
18 | t.close();
19 | }
20 |
21 | static class MyTask extends Thread {
22 | private volatile boolean closed = false;
23 |
24 | @Override
25 | public void run() {
26 | System.out.println("I will start work.");
27 | while (!closed && !isInterrupted()) {
28 |
29 | }
30 | System.out.println("I will be exiting.");
31 | }
32 |
33 | public void close() {
34 | this.closed = true;
35 | this.interrupt();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution922.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2019/01/15
7 | */
8 | public class Solution922 {
9 |
10 | public int[] sortArrayByParityII(int[] A) {
11 | if (null == A || 1 >= A.length) {
12 | return A;
13 | }
14 |
15 | // 偶数指针(even pointer)
16 | int i = 0;
17 | // 奇数指针(odd pointer)
18 | int j = 1;
19 | while (i < A.length && j < A.length) {
20 | while (i < A.length && 0 == (A[i] & 1)) {
21 | i += 2;
22 | }
23 | while (j < A.length && 1 == (A[j] & 1)) {
24 | j += 2;
25 | }
26 | if (i < A.length && j < A.length) {
27 | swap(A, i, j);
28 | }
29 | }
30 | return A;
31 | }
32 |
33 | public void swap(int[] array, int i, int j) {
34 | int tmp = array[i];
35 | array[i] = array[j];
36 | array[j] = tmp;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution006.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 回文判断
6 | * 时间复杂度: O(n)
7 | * 空间复杂度: O(1)
8 | * @date:
9 | */
10 | public class Solution006 {
11 |
12 | public static void main(String[] args) {
13 | final String text1 = "abcd";
14 | final String text2 = "abcdcba";
15 | final String text3 = "123454321";
16 |
17 | System.out.println(isPalindrome(text1));
18 | System.out.println(isPalindrome(text2));
19 | System.out.println(isPalindrome(text3));
20 | }
21 |
22 | public static boolean isPalindrome(String str) {
23 | if (null == str) {
24 | return false;
25 | }
26 |
27 | int start = 0;
28 | int end = str.length() - 1;
29 | while (start < end) {
30 | if (str.charAt(start) != str.charAt(end)) {
31 | return false;
32 | }
33 | ++start;
34 | --end;
35 | }
36 |
37 | return true;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution110.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 平衡二叉树
6 | * @date: 2019/03/07
7 | */
8 | public class Solution110 {
9 |
10 | public boolean isBalanced(TreeNode root) {
11 | return dfs(root) != -1;
12 | }
13 |
14 | public int dfs(TreeNode root) {
15 | if (null == root) {
16 | return 0;
17 | }
18 |
19 | int leftHeight = dfs(root.left);
20 | if (leftHeight == -1) {
21 | return -1;
22 | }
23 | int rightHeight = dfs(root.right);
24 | if (rightHeight == -1) {
25 | return -1;
26 | }
27 |
28 | if (Math.abs(leftHeight - rightHeight) > 1) {
29 | return -1;
30 | }
31 | return Math.max(leftHeight, rightHeight) + 1;
32 | }
33 |
34 | class TreeNode {
35 | int val;
36 | TreeNode left;
37 | TreeNode right;
38 |
39 | TreeNode(int x) {
40 | val = x;
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution532.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 数组中的K-diff数对
9 | * @date: 2019/01/10
10 | */
11 | public class Solution532 {
12 |
13 | public int findPairs(int[] nums, int k) {
14 | if (null == nums || 0 >= nums.length || 0 > k) {
15 | return 0;
16 | }
17 |
18 | Map map = new HashMap<>(nums.length);
19 | for (int n : nums) {
20 | map.put(n, 1 + map.getOrDefault(n, 0));
21 | }
22 |
23 | int ans = 0;
24 | for (Map.Entry entry : map.entrySet()) {
25 | if (0 == k) {
26 | if (2 <= entry.getValue()) {
27 | ++ans;
28 | }
29 | } else {
30 | if (map.containsKey(entry.getKey() + k)) {
31 | ++ans;
32 | }
33 | }
34 | }
35 | return ans;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution011.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最大连续子数组和
6 | * 时间复杂度: O(n)
7 | * 空间复杂度: O(1)
8 | * @date:
9 | */
10 | public class Solution011 {
11 |
12 | public static void main(String[] args) {
13 | int[] array = {1, -2, 3, 10, -4, 7, 2, -5};
14 |
15 | System.out.println(maxSubArray(array));
16 | }
17 |
18 | public static int maxSubArray(int[] array) {
19 | if (null == array || 0 >= array.length) {
20 | return 0;
21 | }
22 |
23 | // 以前一位置元素结尾的最大连续子数组的和
24 | int preSum = 0;
25 | // 最大连续子数组的和
26 | int maxSum = array[0];
27 | for (int i = 0; i < array.length; ++i) {
28 | if (0 <= preSum) {
29 | preSum += array[i];
30 | } else {
31 | preSum = array[i];
32 | }
33 |
34 | if (preSum > maxSum) {
35 | maxSum = preSum;
36 | }
37 | }
38 |
39 | return maxSum;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/bishi/iqiyi/Main091501.java:
--------------------------------------------------------------------------------
1 | package bishi.iqiyi;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | */
7 | public class Main091501 {
8 | public static void main(String[] args) {
9 | Scanner sc = new Scanner(System.in);
10 |
11 | String[] numbers = sc.nextLine().split("\\s+");
12 | int k = Integer.parseInt(sc.nextLine());
13 |
14 | for (int i = 0; i < numbers.length; i += k) {
15 | reverse(numbers, i, i + k - 1);
16 | }
17 |
18 | for (int i = 0; i < numbers.length; ++i) {
19 | System.out.print(numbers[i] + " ");
20 | }
21 | }
22 |
23 | private static void reverse(String[] strs, int start, int end) {
24 | if (end >= strs.length) {
25 | return;
26 | }
27 |
28 | while (start < end) {
29 | String temp = strs[start];
30 | strs[start] = strs[end];
31 | strs[end] = temp;
32 |
33 | ++start;
34 | --end;
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/src/main/java/bishi/iqiyi/Main091502.java:
--------------------------------------------------------------------------------
1 | package bishi.iqiyi;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | */
7 | public class Main091502 {
8 | public static void main(String[] args) {
9 | Scanner sc = new Scanner(System.in);
10 |
11 | int n = Integer.parseInt(sc.nextLine());
12 |
13 | if (n < 5) {
14 | System.out.println(0);
15 | return;
16 | }
17 |
18 | int sum = 0;
19 | int pre = 0;
20 | int current = 0;
21 | for (int i = 5; i <= n; ++i) {
22 | current = pre + countNumberOf5(i);
23 |
24 | sum += current;
25 |
26 | pre = current;
27 | }
28 |
29 | System.out.println(sum);
30 | }
31 |
32 | public static int countNumberOf5(int n) {
33 | int ans = 0;
34 |
35 | if (5 > n || 0 != (n % 5)) {
36 | return ans;
37 | } else {
38 | ++ans;
39 | return ans + countNumberOf5(n / 5);
40 | }
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt03/ThreadSleep.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt03;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/06/29
7 | */
8 | public class ThreadSleep {
9 | public static void main(String[] args) {
10 | new Thread(() -> {
11 | long startTime = System.currentTimeMillis();
12 | sleep(2_000L);
13 | long endTime = System.currentTimeMillis();
14 | System.out.println(String.format("Current Thread Total spend %d ms", (endTime - startTime)));
15 | }).start();
16 |
17 | long startTime = System.currentTimeMillis();
18 | sleep(3_000L);
19 | long endTime = System.currentTimeMillis();
20 | System.out.println(String.format("Main Thread total spend %d ms", (endTime - startTime)));
21 |
22 | }
23 |
24 | private static void sleep(long ms) {
25 | try {
26 | if (ms < 0) {
27 | ms = 0;
28 | }
29 | Thread.sleep(ms);
30 | } catch (InterruptedException e) {
31 |
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution337.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 打家劫舍 III
6 | * @date: 2019/03/12
7 | */
8 | public class Solution337 {
9 | public int rob(TreeNode root) {
10 | int[] ans = dfs(root);
11 | return Math.max(ans[0], ans[1]);
12 | }
13 |
14 | public int[] dfs(TreeNode node) {
15 | if (null == node) {
16 | return new int[2];
17 | }
18 |
19 | int[] left = dfs(node.left);
20 | int[] right = dfs(node.right);
21 | int[] ans = new int[2];
22 | // ans[0] 表示不抢劫该节点,则可获得的最大收益为,左子树和右子树的最大收益之和
23 | ans[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
24 | // ans[1] 表示抢劫该节点,则可获得的最大收益为,不可抢直接相邻的左子树和右子树节点的收益之和
25 | ans[1] = node.val + left[0] + right[0];
26 | return ans;
27 | }
28 |
29 | public class TreeNode {
30 | int val;
31 | TreeNode left;
32 | TreeNode right;
33 |
34 | TreeNode(int x) {
35 | val = x;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution646.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/08/22
9 | */
10 | public class Solution646 {
11 | public int findLongestChain(int[][] pairs) {
12 | if (null == pairs || 0 >= pairs.length) {
13 | return 0;
14 | }
15 |
16 | // 按照第一个元素从小到大排序
17 | Arrays.sort(pairs, (a, b) -> (a[0] - b[0]));
18 | // 以该位置数对作为链表的尾端,串的最大长度
19 | int[] dp = new int[pairs.length];
20 | Arrays.fill(dp, 1);
21 |
22 | for (int i = 0; i < pairs.length; ++i) {
23 | for (int j = 0; j < i; ++j) {
24 | if (pairs[j][1] < pairs[i][0]) {
25 | dp[i] = Math.max(dp[i], dp[j] + 1);
26 | }
27 | }
28 | }
29 |
30 | int max = dp[0];
31 | for (int i = 1; i < dp.length; ++i) {
32 | if (max < dp[i]) {
33 | max = dp[i];
34 | }
35 | }
36 | return max;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution649.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.ArrayDeque;
4 |
5 | /**
6 | * @author Administrator
7 | * @desc Dota2 参议院
8 | * @create 2019/01/22
9 | */
10 | public class Solution649 {
11 |
12 | public String predictPartyVictory(String senate) {
13 | ArrayDeque r = new ArrayDeque<>();
14 | ArrayDeque d = new ArrayDeque<>();
15 | for (int i = 0; i < senate.length(); ++i) {
16 | if ('R' == senate.charAt(i)) {
17 | r.add(i);
18 | } else {
19 | d.add(i);
20 | }
21 | }
22 |
23 | int n = senate.length();
24 | while (!r.isEmpty() && !d.isEmpty()) {
25 | int r_id = r.pollFirst();
26 | int d_id = d.pollFirst();
27 | if (r_id < d_id) {
28 | r.addLast(r_id + n);
29 | } else {
30 | d.addLast(d_id + n);
31 | }
32 | }
33 |
34 | return r.size() > d.size() ? "Radiant" : "Dire";
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution022.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 括号生成
9 | * @date: 2018/07/16
10 | */
11 | public class Solution022 {
12 |
13 | public static void main(String[] args) {
14 | System.out.println(new Solution022().generateParenthesis(3));
15 | }
16 |
17 | public List generateParenthesis(int n) {
18 | List ans = new ArrayList<>();
19 | dfs(ans, "", n, 0, 0);
20 | return ans;
21 | }
22 |
23 | public void dfs(List ans, String oneAnswer, int n, int left, int right) {
24 | if (right == n) {
25 | ans.add(oneAnswer);
26 | return;
27 | }
28 |
29 | // 左括号数量少于 n ,优先添加左括号
30 | if (left < n) {
31 | dfs(ans, oneAnswer + "(", n, left + 1, right);
32 | }
33 | // 右括号数量少于左括号数量 ,添加右括号与左括号配对
34 | if (right < left) {
35 | dfs(ans, oneAnswer + ")", n, left, right + 1);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution870.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 | import java.util.PriorityQueue;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 优势洗牌
9 | * @date: 2019/02/08
10 | */
11 | public class Solution870 {
12 |
13 | public int[] advantageCount(int[] A, int[] B) {
14 | if (0 == A.length && 0 == B.length) {
15 | return A;
16 | }
17 |
18 | Arrays.sort(A);
19 | PriorityQueue queue = new PriorityQueue<>((a, b) -> b[1] - a[1]);
20 | for (int i = 0; i < B.length; ++i) {
21 | queue.add(new int[]{i, B[i]});
22 | }
23 |
24 | int[] ans = new int[A.length];
25 | int low = 0, high = A.length - 1;
26 | while (!queue.isEmpty()) {
27 | int[] cur = queue.poll();
28 | int idx = cur[0], val = cur[1];
29 | if (A[high] > val) {
30 | ans[idx] = A[high--];
31 | } else {
32 | ans[idx] = A[low++];
33 | }
34 | }
35 | return ans;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt01/TryConcurrency.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt01;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/06/27
9 | */
10 | public class TryConcurrency {
11 | public static void main(String[] args) {
12 | new Thread(TryConcurrency::enjoyMusic).start();
13 | new Thread(TryConcurrency::browseNews).start();
14 | }
15 |
16 | private static void browseNews() {
17 | while (true) {
18 | System.out.println("游览网页中...");
19 | sleep(1);
20 | }
21 | }
22 |
23 | private static void enjoyMusic() {
24 | while (true) {
25 | System.out.println("听音乐中...");
26 | sleep(1);
27 | }
28 | }
29 |
30 | private static void sleep(int seconds) {
31 | if (seconds < 0) {
32 | seconds = 0;
33 | }
34 |
35 | try {
36 | TimeUnit.SECONDS.sleep(seconds);
37 | } catch (InterruptedException e) {
38 | e.printStackTrace();
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt04/TicketWindowRunnable.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt04;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/07/01
7 | */
8 | public class TicketWindowRunnable implements Runnable {
9 | private int index = 1;
10 |
11 | private final static int MAX = 50;
12 |
13 | private final static Object MUTEX = new Object();
14 |
15 | @Override
16 | public void run() {
17 | synchronized (MUTEX) {
18 | while (index <= MAX) {
19 | System.out.println(Thread.currentThread() + " 的号码是:" + (index++));
20 | }
21 | }
22 | }
23 |
24 | public static void main(String[] args) {
25 | final TicketWindowRunnable task = new TicketWindowRunnable();
26 |
27 | Thread t1 = new Thread(task, "1号窗口");
28 |
29 | Thread t2 = new Thread(task, "2号窗口");
30 |
31 | Thread t3 = new Thread(task, "3号窗口");
32 |
33 | Thread t4 = new Thread(task, "4号窗口");
34 |
35 | t1.start();
36 | t2.start();
37 | t3.start();
38 | t4.start();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/alg4/Solution002.java:
--------------------------------------------------------------------------------
1 | package algorithm.alg4;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二分查找的递归实现
6 | * @date: 2018/10/28
7 | */
8 | public class Solution002 {
9 |
10 | public static void main(String[] args) {
11 | int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
12 | int key = 6;
13 |
14 | System.out.print("key==" + key + "的下标为: ");
15 | System.out.println(binarySearch(array, key));
16 | }
17 |
18 | public static int binarySearch(int[] array, int key) {
19 | return binarySearch(array, key, 0, array.length);
20 | }
21 |
22 | public static int binarySearch(int[] array, int key, int left, int right) {
23 | if (left > right) {
24 | return -1;
25 | }
26 |
27 | int mid = left + (right - left) / 2;
28 | if (key < array[mid]) {
29 | return binarySearch(array, key, left, mid - 1);
30 | } else if (key > array[mid]) {
31 | return binarySearch(array, key, mid + 1, right);
32 | } else {
33 | return mid;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution069.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/19
7 | */
8 | public class Solution069 {
9 | public static void main(String[] args){
10 | Solution069 test = new Solution069();
11 |
12 | System.out.println(test.mySqrt(1));
13 | System.out.println(test.mySqrt(2));
14 | System.out.println(test.mySqrt(3));
15 | System.out.println(test.mySqrt(4));
16 | System.out.println(test.mySqrt(9));
17 | }
18 |
19 | public int mySqrt(int x) {
20 | if (1 >= x) {
21 | return x;
22 | }
23 |
24 | int left = 1, right = x;
25 | while (left <= right) {
26 | int mid = left + (right - left) / 2;
27 | int sqrt = x / mid;
28 | if (sqrt == mid) {
29 | return sqrt;
30 | } else if (sqrt < mid) {
31 | right = mid - 1;
32 | } else {
33 | left = mid + 1;
34 | }
35 | }
36 | return right;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution108.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 将有序数组转换为二叉搜索树
6 | * @date: 2019/03/07
7 | */
8 | public class Solution108 {
9 | public TreeNode sortedArrayToBST(int[] nums) {
10 | if (null == nums || 0 >= nums.length) {
11 | return null;
12 | }
13 |
14 | return dfs(nums, 0, nums.length - 1);
15 | }
16 |
17 | private TreeNode dfs(int[] nums, int start, int end) {
18 | if (start > end) {
19 | return null;
20 | }
21 | if (start == end) {
22 | return new TreeNode(nums[start]);
23 | }
24 |
25 | int mid = (start + end) >> 1;
26 | TreeNode node = new TreeNode(nums[mid]);
27 | node.left = dfs(nums, start, mid - 1);
28 | node.right = dfs(nums, mid + 1, end);
29 | return node;
30 | }
31 |
32 | class TreeNode {
33 | int val;
34 | TreeNode left;
35 | TreeNode right;
36 |
37 | TreeNode(int x) {
38 | val = x;
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main090702.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/09/06
9 | */
10 | public class Main090702 {
11 | public static void main(String args[]) {
12 | Scanner scanner = new Scanner(System.in);
13 | int testNumber = Integer.parseInt(scanner.nextLine());
14 |
15 | while (0 < testNumber--) {
16 | String[] temp = scanner.nextLine().split("\\s+");
17 | int n = Integer.parseInt(temp[0]);
18 | int k = Integer.parseInt(temp[1]);
19 | int leave = n - k;
20 | if (0 == k || n == k) {
21 | System.out.println("0 0");
22 | continue;
23 | }
24 | if (2 >= n) {
25 | System.out.println("0 0");
26 | continue;
27 | }
28 |
29 | int min = 0, max = leave;
30 | if (k <= leave) {
31 | max = k - 1;
32 | }
33 |
34 |
35 | System.out.println(min + " " + max);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution841.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 字符的最短距离
6 | * Initial result array.
7 | * Loop twice on the string S.
8 | * First forward pass to find shortest distant to character on left.
9 | * Second backward pass to find shortest distant to character on right.
10 | * @date: 2019/01/11
11 | */
12 | public class Solution841 {
13 |
14 | public int[] shortestToChar(String S, char C) {
15 | if (null == S || 0 >= S.length()) {
16 | return null;
17 | }
18 |
19 | int[] ans = new int[S.length()];
20 | int pos = -S.length();
21 | for (int i = 0; i < S.length(); ++i) {
22 | if (S.charAt(i) == C) {
23 | pos = i;
24 | }
25 | ans[i] = i - pos;
26 | }
27 |
28 | for (int i = S.length() - 1; i >= 0; --i) {
29 | if (S.charAt(i) == C) {
30 | pos = i;
31 | }
32 | ans[i] = Math.min(ans[i], Math.abs(i - pos));
33 | }
34 | return ans;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution375.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 猜数字大小 II
6 | * @date: 2019/02/25
7 | */
8 | public class Solution375 {
9 | public int getMoneyAmount(int n) {
10 | int[][] dp = new int[n + 1][n + 1];
11 | dfs(dp, 1, n);
12 | return dp[1][n];
13 | }
14 |
15 | public int dfs(int[][] dp, int start, int end) {
16 | // [start,end]范围仅1个数字,不需任何代价
17 | if (start >= end) {
18 | return 0;
19 | }
20 | // 当前范围最小需要付出的代价已经计算过,直接返回该值
21 | if (0 != dp[start][end]) {
22 | return dp[start][end];
23 | }
24 |
25 | int ans = Integer.MAX_VALUE;
26 | // 当答案不是n的时候,需要付出的代价,寻找最小的代价
27 | for (int n = start; n <= end; ++n) {
28 | // 需要确保在最极端的情况下也能猜到答案,故需要有足够的钱,因此选择 max
29 | int tmp = n + Math.max(dfs(dp, start, n - 1), dfs(dp, n + 1, end));
30 | if (tmp < ans) {
31 | ans = tmp;
32 | }
33 | }
34 | dp[start][end] = ans;
35 | return ans;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution930.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 和相同的二元子数组
6 | * @date: 2019/01/13
7 | */
8 | public class Solution930 {
9 |
10 | public static void main(String[] args) {
11 | int[] nums = {1, 0, 1, 0, 1, 0, 0, 1, 1, 0};
12 | final int S = 2;
13 |
14 | System.out.println(new Solution930().numSubarraysWithSum(nums, S));
15 | }
16 |
17 | /**
18 | * 统计前缀和出现的次数
19 | *
20 | * @param A
21 | * @param S
22 | * @return
23 | */
24 | public int numSubarraysWithSum(int[] A, int S) {
25 | if (null == A || 0 >= A.length) {
26 | return 0;
27 | }
28 |
29 | int preSum = 0, cnt = 0;
30 | int[] count = new int[A.length + 1];
31 | // preSum与S相等时,仅有1种情况
32 | count[0] = 1;
33 | for (int e : A) {
34 | preSum += e;
35 | if (preSum >= S) {
36 | cnt += count[preSum - S];
37 | }
38 | ++count[preSum];
39 | }
40 | return cnt;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/note/MySearch.java:
--------------------------------------------------------------------------------
1 | package algorithm.note;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/09/01
7 | */
8 | public class MySearch {
9 | public static void main(String[] args) {
10 | int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
11 |
12 | System.out.println(binarySearch(numbers, 8));
13 | }
14 |
15 | /**
16 | * 二分查找:数组需要有序
17 | * @param array
18 | * @param searchKey
19 | * @return
20 | */
21 | public static int binarySearch(int[] array, int searchKey) {
22 | if (null == array || 0 >= array.length) {
23 | return -1;
24 | }
25 |
26 | int left = 0, right = array.length - 1;
27 | while (left <= right) {
28 | int middle = left + (right - left) / 2;
29 | if (searchKey == array[middle]) {
30 | return middle;
31 | } else if (searchKey < array[middle]) {
32 | right = middle - 1;
33 | } else {
34 | left = middle + 1;
35 | }
36 | }
37 | return -1;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution199.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 二叉树的右视图
9 | * @date: 2019/03/13
10 | */
11 | public class Solution199 {
12 | public List rightSideView(TreeNode root) {
13 | List ans = new LinkedList<>();
14 | if (null == root) {
15 | return ans;
16 | }
17 |
18 | dfs(ans, root, 0);
19 | return ans;
20 | }
21 |
22 | public void dfs(List answer, TreeNode node, int depth) {
23 | if (null == node) {
24 | return;
25 | }
26 |
27 | if (answer.size() == depth) {
28 | answer.add(node.val);
29 | }
30 | // 必须先右子树,因为右子树添加节点后左子树就无法添加节点
31 | dfs(answer, node.right, depth + 1);
32 | dfs(answer, node.left, depth + 1);
33 | }
34 |
35 | public class TreeNode {
36 | int val;
37 | TreeNode left;
38 | TreeNode right;
39 |
40 | TreeNode(int x) {
41 | val = x;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution516.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最长回文子序列
6 | * @date: 2019/02/26
7 | */
8 | public class Solution516 {
9 | public int longestPalindromeSubseq(String s) {
10 | if (null == s || 0 >= s.length()) {
11 | return 0;
12 | }
13 |
14 | int n = s.length();
15 | // dp[i][j]代表: substring(i, j)的最长回文子串
16 | // here i, j represent left, right indexes in the string
17 | int[][] dp = new int[n][n];
18 |
19 | // dp[i][j] = dp[i+1][j-1] + 2 ,如果s.charAt(i) == s.charAt(j)
20 | // 否则, dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1])
21 |
22 | for (int i = n - 1; i >= 0; --i) {
23 | dp[i][i] = 1;
24 | for (int j = i + 1; j < n; ++j) {
25 | if (s.charAt(i) == s.charAt(j)) {
26 | dp[i][j] = dp[i + 1][j - 1] + 2;
27 | } else {
28 | dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
29 | }
30 | }
31 | }
32 | return dp[0][n-1];
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution784.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 字母大小写全排列
9 | * @date: 2019/02/16
10 | */
11 | public class Solution784 {
12 |
13 | public List letterCasePermutation(String S) {
14 | List ans = new LinkedList<>();
15 |
16 | if (null == S) {
17 | return ans;
18 | }
19 |
20 | dfs(ans, S.toCharArray(), 0);
21 | return ans;
22 | }
23 |
24 | public void dfs(List answer, char[] chs, int start) {
25 | if (start == chs.length) {
26 | answer.add(new String(chs));
27 | return;
28 | }
29 |
30 | if ('0' <= chs[start] && chs[start] <= '9') {
31 | dfs(answer, chs, start + 1);
32 | } else {
33 | chs[start] = Character.toLowerCase(chs[start]);
34 | dfs(answer, chs, start + 1);
35 |
36 | chs[start] = Character.toUpperCase(chs[start]);
37 | dfs(answer, chs, start + 1);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution300.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最长上升子序列
6 | * @date: 2018/08/22
7 | */
8 | public class Solution300 {
9 | public static void main(String[] args) {
10 | int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};
11 |
12 | Solution300 test = new Solution300();
13 | System.out.println(test.lengthOfLIS(nums));
14 | }
15 |
16 | public int lengthOfLIS(int[] nums) {
17 | if (null == nums || 0 >= nums.length) {
18 | return 0;
19 | }
20 |
21 | int ans = Integer.MIN_VALUE;
22 | // dp[i]表示:以第i个位置结尾的最长上升子序列
23 | int[] dp = new int[nums.length];
24 | for (int i = 0; i < nums.length; ++i) {
25 | int mx = 1;
26 | for (int j = 0; j < i; ++j) {
27 | if (nums[i] > nums[j]) {
28 | mx = Math.max(mx, dp[j] + 1);
29 | }
30 | }
31 | dp[i] = mx;
32 | if (dp[i] > ans) {
33 | ans = dp[i];
34 | }
35 | }
36 |
37 | return ans;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution343.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 整数拆分
6 | * @date: 2018/08/22
7 | */
8 | public class Solution343 {
9 | public static void main(String[] args) {
10 | Solution343 test = new Solution343();
11 |
12 | System.out.println(test.integerBreak(10));
13 | System.out.println(test.integerBreak2(10));
14 | }
15 |
16 | public int integerBreak(int n) {
17 | // 第 n 个位置表示:数字 n 分解后可获得的最大乘积
18 | int[] dp = new int[n + 1];
19 | for (int i = 1; i <= n; ++i) {
20 | for (int j = 1; j < i; ++j) {
21 | dp[i] = Math.max(dp[i], Math.max(j * dp[i - j], j * (i - j)));
22 | }
23 | }
24 | return dp[n];
25 | }
26 |
27 | public int integerBreak2(int n) {
28 | int ans = 1;
29 |
30 | if (4 >= n) {
31 | return (4 == n) ? 4 : n - 1;
32 | }
33 |
34 | // 分解该数字后,数字3的数量越多,乘积越大
35 | while (4 < n) {
36 | ans *= 3;
37 | n -= 3;
38 | }
39 |
40 | return ans * n;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt04/ThisMonitor.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt04;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import static java.lang.Thread.currentThread;
6 |
7 | /**
8 | * @author: mayuan
9 | * @desc:
10 | * @date: 2018/07/02
11 | */
12 | public class ThisMonitor {
13 |
14 | public static void main(String[] args) {
15 | ThisMonitor thisMonitor = new ThisMonitor();
16 | new Thread(thisMonitor::method1, "T1").start();
17 | new Thread(thisMonitor::method2, "T2").start();
18 | }
19 |
20 | public synchronized void method1() {
21 | System.out.println(currentThread().getName() + " enter to method1.");
22 | try {
23 | TimeUnit.MINUTES.sleep(10);
24 | } catch (InterruptedException e) {
25 | e.printStackTrace();
26 | }
27 | }
28 |
29 | public synchronized void method2() {
30 | System.out.println(currentThread().getName() + " enter to method2.");
31 | try {
32 | TimeUnit.MINUTES.sleep(10);
33 | } catch (InterruptedException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution144.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 二叉树的前序遍历
9 | * @date: 2019/03/09
10 | */
11 | public class Solution144 {
12 | public List preorderTraversal(TreeNode root) {
13 | List ans = new LinkedList<>();
14 | if (null == root) {
15 | return ans;
16 | }
17 |
18 | LinkedList stack = new LinkedList<>();
19 | stack.push(root);
20 |
21 | while (!stack.isEmpty()) {
22 | TreeNode cur = stack.pop();
23 | ans.add(cur.val);
24 |
25 | if (null != cur.right) {
26 | stack.push(cur.right);
27 | }
28 | if (null != cur.left) {
29 | stack.push(cur.left);
30 | }
31 | }
32 |
33 | return ans;
34 | }
35 |
36 | public class TreeNode {
37 | int val;
38 | TreeNode left;
39 | TreeNode right;
40 |
41 | TreeNode(int x) {
42 | val = x;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main0909002.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.Arrays;
4 | import java.util.Scanner;
5 |
6 | /**
7 | */
8 | public class Main0909002 {
9 | public static void main(String[] args) {
10 | Scanner scanner = new Scanner(System.in);
11 | int n = Integer.parseInt(scanner.nextLine());
12 |
13 | int[][] matrix = new int[n][3];
14 | for (int i = 0; i < n; ++i) {
15 | matrix[i][0] = scanner.nextInt();
16 | matrix[i][1] = scanner.nextInt();
17 | matrix[i][2] = scanner.nextInt();
18 | }
19 |
20 | Arrays.sort(matrix, (a, b) -> (a[0] - b[0]));
21 |
22 | int ans = 0;
23 | for (int i = 0; i < n; ++i) {
24 | for (int j = 0; j < n; ++j) {
25 | if ((matrix[i][0] < matrix[j][0]) &&
26 | (matrix[i][1] < matrix[j][1]) &&
27 | (matrix[i][2] < matrix[j][2])) {
28 | ++ans;
29 | break;
30 | }
31 | }
32 | }
33 |
34 | System.out.println(ans);
35 | }
36 | }
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution763.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 划分字母区间
9 | * @date: 2018/08/19
10 | */
11 | public class Solution763 {
12 | public static void main(String[] args) {
13 | Solution763 test = new Solution763();
14 |
15 | List ans = test.partitionLabels("ababcbacadefegdehijhklij");
16 | ans.forEach(System.out::println);
17 | }
18 |
19 | public List partitionLabels(String S) {
20 | int[] map = new int[26];
21 | for (int i = 0; i < S.length(); ++i) {
22 | map[S.charAt(i) - 'a'] = i;
23 | }
24 |
25 | List answer = new LinkedList<>();
26 | int start = 0, last = 0;
27 | for (int i = 0; i < S.length(); ++i) {
28 | last = last > map[S.charAt(i) - 'a'] ? last : map[S.charAt(i) - 'a'];
29 | if (last == i) {
30 | answer.add(last - start + 1);
31 | start = last + 1;
32 | }
33 | }
34 | return answer;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution859.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/12/25
7 | */
8 | public class Solution859 {
9 |
10 | public boolean buddyStrings(String A, String B) {
11 | if (null == A || null == B || A.length() != B.length() || 0 == A.length()) {
12 | return false;
13 | }
14 |
15 | int indexA = -1, indexB = -1, diff = 0;
16 | int[] map = new int[26];
17 | boolean duplicate = false;
18 |
19 | for (int i = 0; i < A.length(); ++i) {
20 | if (++map[A.charAt(i) - 'a'] >= 2) {
21 | duplicate = true;
22 | }
23 | if (A.charAt(i) != B.charAt(i)) {
24 | ++diff;
25 | if (-1 == indexA) {
26 | indexA = i;
27 | } else if (-1 == indexB) {
28 | indexB = i;
29 | }
30 | }
31 | }
32 | return (0 == diff && duplicate) ||
33 | (2 == diff && A.charAt(indexA) == B.charAt(indexB) && A.charAt(indexB) == B.charAt(indexA));
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution017.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二叉树的最近公共祖先
6 | * @date: 2018/12/02
7 | */
8 | public class Solution017 {
9 |
10 | /**
11 | * 在root为根的二叉树中找A,B的LCA:
12 | * 如果找到了就返回这个LCA
13 | * 如果只碰到A,就返回A
14 | * 如果只碰到B,就返回B
15 | * 如果都没有,就返回null
16 | *
17 | * @param root
18 | * @param p
19 | * @param q
20 | * @return
21 | */
22 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
23 | if (null == root || p == root || q == root) {
24 | return root;
25 | }
26 |
27 | TreeNode left = lowestCommonAncestor(root.left, p, q);
28 | TreeNode right = lowestCommonAncestor(root.right, p, q);
29 | if (null != left && null != right) {
30 | return root;
31 | }
32 |
33 | return null != left ? left : right;
34 | }
35 |
36 | private static class TreeNode {
37 | int val;
38 | TreeNode left;
39 | TreeNode right;
40 |
41 | TreeNode(int x) {
42 | val = x;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution001.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 两数之和
9 | * 时间复杂度: O(n) 只遍历了包含有 n 个元素的列表一次。在哈希表中进行的每次查找只花费 O(1)的时间。
10 | * 空间复杂度: O(n) 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 n 个元素
11 | * @date: 2018/11/18
12 | */
13 | public class Solution001 {
14 |
15 | /**
16 | * 依次顺序扫描数组,每次从哈希表中查询是否存在对应的相加之和为 target 的数字,
17 | * 存在则直接将它们的下标放入数组返回,不存在则将当前数字和下标放入哈希表.
18 | * key -> 该数字
19 | * value -> 该数字的下标
20 | */
21 | public int[] twoSum(int[] nums, int target) {
22 | if (null == nums || 0 >= nums.length) {
23 | return null;
24 | }
25 |
26 | Map map = new HashMap<>(nums.length);
27 | int pos;
28 | for (int i = 0; i < nums.length; ++i) {
29 | int number = target - nums[i];
30 | if (-1 != (pos = map.getOrDefault(number, -1))) {
31 | return new int[]{i, pos};
32 | } else {
33 | map.put(nums[i], i);
34 | }
35 | }
36 |
37 | return null;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution142.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 环形链表 II
6 | * @date: 2019/01/04
7 | */
8 | public class Solution142 {
9 |
10 | public ListNode detectCycle(ListNode head) {
11 | if (null == head) {
12 | return null;
13 | }
14 |
15 | boolean isCycle = false;
16 | ListNode slow = head, fast = head;
17 | while (null != fast && null != fast.next) {
18 | fast = fast.next.next;
19 | slow = slow.next;
20 |
21 | if (slow == fast) {
22 | isCycle = true;
23 | break;
24 | }
25 | }
26 |
27 | if (!isCycle) {
28 | return null;
29 | }
30 | fast = head;
31 | while (fast != slow) {
32 | fast = fast.next;
33 | slow = slow.next;
34 | }
35 | return slow;
36 | }
37 |
38 | class ListNode {
39 | int val;
40 | ListNode next;
41 |
42 | ListNode(int x) {
43 | val = x;
44 | next = null;
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution236.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 二叉树的最近公共祖先
6 | * @date: 2018/12/02
7 | */
8 | public class Solution236 {
9 |
10 | /**
11 | * 在root为根的二叉树中找A,B的LCA:
12 | * 如果找到了就返回这个LCA
13 | * 如果只碰到A,就返回A
14 | * 如果只碰到B,就返回B
15 | * 如果都没有,就返回null
16 | *
17 | * @param root
18 | * @param p
19 | * @param q
20 | * @return
21 | */
22 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
23 | if (null == root || p == root || q == root) {
24 | return root;
25 | }
26 |
27 | TreeNode left = lowestCommonAncestor(root.left, p, q);
28 | TreeNode right = lowestCommonAncestor(root.right, p, q);
29 | if (null != left && null != right) {
30 | return root;
31 | }
32 |
33 | return null != left ? left : right;
34 | }
35 |
36 | private static class TreeNode {
37 | int val;
38 | TreeNode left;
39 | TreeNode right;
40 |
41 | TreeNode(int x) {
42 | val = x;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution467.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 环绕字符串中唯一的子字符串
6 | * @date: 2019/03/02
7 | */
8 | public class Solution467 {
9 | public int findSubstringInWraproundString(String p) {
10 | // count[i] is the maximum unique substring end with ith letter.
11 | // 0 - 'a', 1 - 'b', ..., 25 - 'z'.
12 | int[] count = new int[26];
13 |
14 | // store longest contiguous substring ends at current position.
15 | int maxLengthCur = 0;
16 |
17 | for (int i = 0; i < p.length(); i++) {
18 | if (i > 0 && (p.charAt(i) - p.charAt(i - 1) == 1 || (p.charAt(i - 1) - p.charAt(i) == 25))) {
19 | maxLengthCur++;
20 | } else {
21 | maxLengthCur = 1;
22 | }
23 |
24 | int index = p.charAt(i) - 'a';
25 | count[index] = Math.max(count[index], maxLengthCur);
26 | }
27 |
28 | // Sum to get result
29 | int sum = 0;
30 | for (int i = 0; i < 26; i++) {
31 | sum += count[i];
32 | }
33 | return sum;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main090901.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.HashSet;
4 | import java.util.Scanner;
5 | import java.util.Set;
6 |
7 | /**
8 | * @author: mayuan
9 | * @desc:
10 | * @date: 2018/09/09
11 | */
12 | public class Main090901 {
13 | public static void main(String args[]) {
14 | Scanner scanner = new Scanner(System.in);
15 |
16 | String str = scanner.nextLine();
17 |
18 | int maxLength = 0;
19 | Set set = new HashSet<>();
20 |
21 | int count = 0;
22 | for (int i = 0; i < str.length(); ++i) {
23 | char c = str.charAt(i);
24 | if (!set.contains(c)) {
25 | set.add(c);
26 | ++count;
27 | if (maxLength < count) {
28 | maxLength = count;
29 | }
30 | } else {
31 | count = 1;
32 | if (maxLength < count) {
33 | maxLength = count;
34 | }
35 | set.clear();
36 | set.add(c);
37 | }
38 | }
39 |
40 | System.out.println(maxLength);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution021.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最大连续乘积子数组
6 | * 时间复杂度: O(n)
7 | * 空间复杂度: O(1)
8 | * @date:
9 | */
10 | public class Solution021 {
11 |
12 | public static void main(String[] args) {
13 | double[] array = {-2.5, 4, 0, 3, 0.5, 8, -1};
14 |
15 | System.out.println(maxSubArray(array));
16 | }
17 |
18 | public static double maxSubArray(double[] array) {
19 | if (null == array || 0 >= array.length) {
20 | return 0.0D;
21 | }
22 |
23 | double ans = array[0];
24 | double maxEnd = array[0];
25 | double minEnd = array[0];
26 | for (int i = 1; i < array.length; ++i) {
27 | // 当前数字为正数时,以其结尾的最大乘积子数组来自于之前的最大
28 | // 当前数字为负数时,以其结尾的最大乘积子数组来自于之前的最小
29 | double end1 = maxEnd * array[i];
30 | double end2 = minEnd * array[i];
31 | maxEnd = Math.max(array[i], Math.max(end1, end2));
32 | minEnd = Math.min(array[i], Math.min(end1, end2));
33 |
34 | ans = Math.max(ans, maxEnd);
35 | }
36 | return ans;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution844.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 比较含退格的字符串
6 | * @date: 2019/01/12
7 | */
8 | public class Solution844 {
9 |
10 | /**
11 | * The idea is that, read next letter from end to start.
12 | * If we meet #, we increase the number we need to step back, until back = 0
13 | * @param S
14 | * @param T
15 | * @return
16 | */
17 | public boolean backspaceCompare(String S, String T) {
18 | if ((null == S && null != T) || (null != S && null == T)) {
19 | return false;
20 | }
21 |
22 | for (int i = S.length() - 1, j = T.length() - 1; ; --i, --j) {
23 | for (int b = 0; i >= 0 && (b > 0 || '#' == S.charAt(i)); --i) {
24 | b += '#' == S.charAt(i) ? 1 : -1;
25 | }
26 | for (int b = 0; j >= 0 && (b > 0 || '#' == T.charAt(j)); --j) {
27 | b += '#' == T.charAt(j) ? 1 : -1;
28 | }
29 |
30 | if (0 > i || 0 > j || S.charAt(i) != T.charAt(j)) {
31 | return -1 == i && -1 == j;
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution416.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 分割等和子集
6 | * @date: 2018/08/23
7 | */
8 | public class Solution416 {
9 | public boolean canPartition(int[] nums) {
10 | int sum = sumOfArray(nums);
11 | // 数组和为奇数,直接返回 false
12 | if (1 == (sum & 1)) {
13 | return false;
14 | }
15 |
16 | int W = sum >>> 1;
17 | // dp[i] 代表能否组合成和为 i 的结果。
18 | boolean[] dp = new boolean[W + 1];
19 | dp[0] = true;
20 |
21 | // 对于每一个数字,选择都是两个,放或者不放。所以,
22 | // 如果不放第 i 个数字,那问题就变成了前 i - 1 个数字能否组合成和为 j 的结果;
23 | // 如果放第 i 个数字,那问题就变成了前 i - 1 个数字能否组合成和为 j - nums[i] 的结果。
24 | // 只要这两种情况有一种存在, dp[j] 就成立。
25 | for (int e : nums) {
26 | // 必须从大到小
27 | for (int j = W; j >= e; --j) {
28 | dp[j] = dp[j] || dp[j - e];
29 | }
30 | }
31 | return dp[W];
32 | }
33 |
34 | private int sumOfArray(int[] nums) {
35 | int sum = 0;
36 | for (int n : nums) {
37 | sum += n;
38 | }
39 | return sum;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution179.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Arrays;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc: 最大数
8 | * @date: 2019/01/14
9 | */
10 | public class Solution179 {
11 |
12 | public static void main(String[] args) {
13 | int[] nums = {3, 30, 34, 5, 9};
14 | System.out.println(new Solution179().largestNumber(nums));
15 | }
16 |
17 | public String largestNumber(int[] nums) {
18 | if (null == nums || 0 >= nums.length) {
19 | return "0";
20 | }
21 |
22 | String[] strNums = new String[nums.length];
23 | for (int i = 0; i < nums.length; ++i) {
24 | strNums[i] = String.valueOf(nums[i]);
25 | }
26 | Arrays.sort(strNums, (a, b) -> (b + a).compareTo(a + b));
27 |
28 | // 特殊情况处理: [0, 0, 0] -> 0
29 | if ('0' == strNums[0].charAt(0)) {
30 | return "0";
31 | }
32 |
33 | StringBuilder stringBuilder = new StringBuilder();
34 | for (String e : strNums) {
35 | stringBuilder.append(e);
36 | }
37 |
38 | return stringBuilder.toString();
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution680.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/17
7 | */
8 | public class Solution680 {
9 | public static void main(String[] args) {
10 | Solution680 test = new Solution680();
11 |
12 | System.out.println(test.validPalindrome("aba"));
13 | System.out.println(test.validPalindrome("abcda"));
14 | }
15 |
16 | public boolean validPalindrome(String s) {
17 | int left = 0;
18 | int right = s.length() - 1;
19 | while (left < right) {
20 | if (s.charAt(left) != s.charAt(right)) {
21 | return isPalindrome(s, left, right - 1) || isPalindrome(s, left + 1, right);
22 | }
23 | ++left;
24 | --right;
25 | }
26 | return true;
27 | }
28 |
29 | private boolean isPalindrome(String s, int left, int right) {
30 | while (left < right) {
31 | if (s.charAt(left) != s.charAt(right)) {
32 | return false;
33 | }
34 | ++left;
35 | --right;
36 | }
37 | return true;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/str/Problem042.java:
--------------------------------------------------------------------------------
1 | package algorithm.str;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最长回文子串 leetcode 005
6 | * @date: 2018/09/07
7 | */
8 | public class Problem042 {
9 | private int index;
10 | private int len;
11 |
12 | public static void main(String[] args) {
13 | Problem042 solution = new Problem042();
14 |
15 | System.out.println(solution.longestPalindrome("ac"));
16 | }
17 |
18 | public String longestPalindrome(String s) {
19 | if (null == s || 2 > s.length()) {
20 | return s;
21 | }
22 |
23 | for (int i = 0; i < s.length() - 1; ++i) {
24 | palindromeHelper(s, i, i);
25 | palindromeHelper(s, i, i + 1);
26 | }
27 |
28 | return s.substring(index, index + len);
29 | }
30 |
31 | public void palindromeHelper(String s, int l, int r) {
32 | while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
33 | --l;
34 | ++r;
35 | }
36 |
37 | // 发现更长的回文子序列,则进行更新
38 | if (len < r - l - 1) {
39 | index = l + 1;
40 | len = r - l - 1;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main091601.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | */
7 | public class Main091601 {
8 | public static void main(String[] args) {
9 | Scanner scanner = new Scanner(System.in);
10 | int n = Integer.parseInt(scanner.nextLine());
11 | int[] numbers = new int[n];
12 | int[] sum = new int[n];
13 |
14 | for (int i = 0; i < n; ++i) {
15 | numbers[i] = scanner.nextInt();
16 | if (0 != i) {
17 | sum[i] = sum[i - 1] + numbers[i];
18 | } else {
19 | sum[i] = numbers[0];
20 | }
21 | }
22 |
23 | boolean hasAnswer = false;
24 | int max = (numbers[0] > numbers[1]) ? numbers[0] : numbers[1];
25 | for (int i = 2; i < n; ++i) {
26 | max = (numbers[i] > max) ? numbers[i] : max;
27 | if (max < sum[i] - max) {
28 | hasAnswer = true;
29 | System.out.println(i + 1);
30 | break;
31 | }
32 | }
33 |
34 | if (!hasAnswer) {
35 | System.out.println(-1);
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution583.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/24
7 | */
8 | public class Solution583 {
9 | public int minDistance(String word1, String word2) {
10 | if (null == word1 || null == word2) {
11 | return 0;
12 | }
13 |
14 | int lengthOfWord1 = word1.length();
15 | int lengthOfWord2 = word2.length();
16 | // dp[i][j]表示 word1的第 i 个字符前和 word2的第 j个字符前,最长公共子序列的长度
17 | int[][] dp = new int[lengthOfWord1 + 1][lengthOfWord2 + 1];
18 |
19 | for (int i = 1; i <= lengthOfWord1; ++i) {
20 | for (int j = 1; j <= lengthOfWord2; ++j) {
21 | // word1 的第 i 个字符和 word2 的第 j个字符相等
22 | if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
23 | dp[i][j] = dp[i - 1][j - 1] + 1;
24 | } else {
25 | // word1 的第 i 个字符和 word2 的第 j个字符不相等
26 | dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
27 | }
28 | }
29 | }
30 | return lengthOfWord1 + lengthOfWord2 - 2 * dp[lengthOfWord1][lengthOfWord2];
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution016.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 完美洗牌算法
6 | * 时间复杂度: O(n)
7 | * 空间复杂度:
8 | * @date:
9 | */
10 | public class Solution016 {
11 |
12 | public static void main(String[] args) {
13 | int[] a = {0, 1, 2, 3, 4, 5, 6, 7, 8};
14 |
15 | locationReplace(a);
16 | }
17 |
18 | /**
19 | * 下标从1开始计数
20 | * a1,a2,a3,a4,b1,b2,b3,b4
21 | * n 为4
22 | * 1.当 i <= n 时, 该元素在新数组中的下标为: 2*i
23 | * 2.当 i > n 时, 该元素在新数组中的下标为: (2*i)%(2*n+1)
24 | *
25 | * @param a
26 | */
27 | public static void locationReplace(int[] a) {
28 | if (null == a || 0 >= a.length) {
29 | return;
30 | }
31 |
32 | int[] b = new int[a.length];
33 | int n = (a.length - 1) >>> 1;
34 | int n2 = n * 2;
35 |
36 | for (int i = 1; i < a.length; ++i) {
37 | if (i <= n) {
38 | b[2 * i] = a[i];
39 | } else {
40 | b[(2 * i) % (n2 + 1)] = a[i];
41 | }
42 | }
43 |
44 | for (int num : b) {
45 | System.out.print(num + " ");
46 | }
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt04/ThisMonitor2.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt04;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import static java.lang.Thread.currentThread;
6 |
7 | /**
8 | * @author: mayuan
9 | * @desc:
10 | * @date: 2018/07/02
11 | */
12 | public class ThisMonitor2 {
13 |
14 | public static void main(String[] args) {
15 | ThisMonitor2 thisMonitor = new ThisMonitor2();
16 | new Thread(thisMonitor::method1, "T1").start();
17 | new Thread(thisMonitor::method2, "T2").start();
18 | }
19 |
20 | public synchronized void method1() {
21 | System.out.println(currentThread().getName() + " enter to method1.");
22 | try {
23 | TimeUnit.MINUTES.sleep(10);
24 | } catch (InterruptedException e) {
25 | e.printStackTrace();
26 | }
27 | }
28 |
29 | public void method2() {
30 | synchronized (this) {
31 | System.out.println(currentThread().getName() + " enter to method2.");
32 | try {
33 | TimeUnit.MINUTES.sleep(10);
34 | } catch (InterruptedException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/README.md:
--------------------------------------------------------------------------------
1 | # **编程之法**
2 |
3 | | 题号 | 题目 |
4 | |:----:| ------------------------------------------------------- |
5 | | 1-1 | [字符串的旋转](./Solution001.java) |
6 | | 1-1-1 | [单词翻转](./Solution002.java) |
7 | | 1-2 | [字符串的包含](./Solution003.java) |
8 | | 1-3 | [字符串的全排列](./Solution004.java) |
9 | | 1-4 | [字符串转换成整数](./Solution005.java) |
10 | | 1-5 | [回文判断](./Solution006.java) |
11 | | 1-5-1 | [判断单链表是否为回文](./Solution007.java) |
12 | | 1-6 | [最长回文子串](./Solution008.java) |
13 | | 2-2 | [寻找和为定值的两个数](./Solution009.java) |
14 | | 2-3 | [寻找和为定值的多个数](./Solution010.java) |
15 | | 2-4 | [最大连续子数组和](./Solution011.java) |
16 | | 2-5 | [跳台阶问题](./Solution012.java) |
17 | | 2-6 | [奇偶数排序](./Solution013.java) |
18 | | 2-7 | [荷兰国旗问题](./Solution014.java) |
19 | | 2-8 | [矩阵乘法](./Solution015.java) |
20 | | 2-9 | [完美洗牌算法](./Solution016.java) |
21 | | 3-3 | [二叉树的最近公共祖先](./Solution017.java) |
22 | | 4-1 | [有序数组的查找](./Solution018.java) |
23 | | 4-2 | [行列递增矩阵的查找](./Solution019.java) |
24 | | 4-3 | [出现次数超过一半的数](./Solution020.java) |
25 | | 5-1 | [最大连续乘积子数组](./Solution021.java) |
26 | | 5-2 | [字符串编辑距离](./Solution022.java) |
27 | | 5-4 | [交替字符串](./Solution023.java) |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt03/ThreadPriority.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt03;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/06/30
9 | */
10 | public class ThreadPriority {
11 |
12 | public static void main(String[] args) {
13 | Thread t1 = new Thread(() -> {
14 | while (true) {
15 | System.out.println("t1");
16 | try {
17 | TimeUnit.SECONDS.sleep(2);
18 | } catch (InterruptedException e) {
19 | e.printStackTrace();
20 | }
21 | }
22 | });
23 | // 线程优先级最小为 1, 最大为 10, 默认为 5. 且不能大于线程所在 group 的优先级.
24 | t1.setPriority(3);
25 |
26 | Thread t2 = new Thread(() -> {
27 | while (true) {
28 | System.out.println("t2");
29 | try {
30 | TimeUnit.SECONDS.sleep(2);
31 | } catch (InterruptedException e) {
32 | e.printStackTrace();
33 | }
34 | }
35 | });
36 | t2.setPriority(10);
37 |
38 | t1.start();
39 | t2.start();
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution010.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 寻找和为定值的多个数
9 | * 时间复杂度: O(n!)
10 | * 空间复杂度:
11 | * @date:
12 | */
13 | public class Solution010 {
14 |
15 | public static void main(String[] args) {
16 | sumOfKNumber(10, 10, new LinkedList<>());
17 | }
18 |
19 | /**
20 | * n 问题转化为 n-1 问题
21 | * 1.如果取第 n 个数,则问题转化为取前 n-1 个数使得它们的和为 sum-n
22 | * 2.如果不取第 n 个数,则问题转化为取前 n-1 个数使得它们的和为 sum
23 | *
24 | * @param sum
25 | * @param n
26 | * @param answer
27 | */
28 | public static void sumOfKNumber(int sum, int n, List answer) {
29 | if (0 >= sum || 0 >= n) {
30 | return;
31 | }
32 |
33 | // 找到一组解,直接输出
34 | if (sum == n) {
35 | for (Integer num : answer) {
36 | System.out.print(num + " ");
37 | }
38 | System.out.println(n);
39 | }
40 |
41 | answer.add(n);
42 | sumOfKNumber(sum - n, n - 1, answer);
43 | answer.remove(answer.size() - 1);
44 | sumOfKNumber(sum, n - 1, answer);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution019.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 行列递增矩阵的查找
6 | * 时间复杂度: O(m+n)
7 | * 空间复杂度: O(1)
8 | * @date:
9 | */
10 | public class Solution019 {
11 |
12 | public static void main(String[] args) {
13 | int[][] matrix = {
14 | {1, 2, 8, 9},
15 | {2, 4, 9, 12},
16 | {4, 7, 10, 13},
17 | {6, 8, 11, 15}};
18 |
19 | final int target = 6;
20 | System.out.println(matrixSearch(matrix, target));
21 | }
22 |
23 | public static boolean matrixSearch(int[][] matrix, int target) {
24 | if (null == matrix || 0 >= matrix.length) {
25 | return false;
26 | }
27 |
28 | int i = 0;
29 | int j = matrix[0].length - 1;
30 | while (true) {
31 | if (target == matrix[i][j]) {
32 | return true;
33 | } else if (target > matrix[i][j] && i < matrix.length - 1) {
34 | ++i;
35 | } else if (target < matrix[i][j] && j > 0) {
36 | --j;
37 | } else {
38 | return false;
39 | }
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution167.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 两数之和 II - 输入有序数组
6 | * @date: 2018/08/17
7 | */
8 | public class Solution167 {
9 | public static void main(String[] args) {
10 | int[] nums = {2, 7, 11, 15};
11 | int target = 9;
12 |
13 | Solution167 test = new Solution167();
14 | for (int t : test.twoSum(nums, target)) {
15 | System.out.println(t);
16 | }
17 | }
18 |
19 | public int[] twoSum(int[] numbers, int target) {
20 | int[] answer = new int[2];
21 | if (null == numbers || 2 > numbers.length) {
22 | return answer;
23 | }
24 |
25 | int left = 0;
26 | int right = numbers.length - 1;
27 | while (left < right) {
28 | int temp = numbers[left] + numbers[right];
29 | if (target == temp) {
30 | answer[0] = left + 1;
31 | answer[1] = right + 1;
32 | break;
33 | } else if (target > temp) {
34 | ++left;
35 | } else {
36 | --right;
37 | }
38 | }
39 | return answer;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/CountDownLatchExample.java:
--------------------------------------------------------------------------------
1 | package concurrent;
2 |
3 | import java.util.concurrent.CountDownLatch;
4 | import java.util.concurrent.ExecutorService;
5 | import java.util.concurrent.Executors;
6 |
7 | /**
8 | * @author: mayuan
9 | * @desc: 用来控制一个线程等待多个线程。(某个线程等待多个线程到达)
10 | * 维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那个因为调用 await() 方法而在等待的线程就会被唤醒。
11 | * @date: 2018/09/14
12 | */
13 | public class CountDownLatchExample {
14 |
15 | public static void main(String[] args) {
16 | final int totalThread = 10;
17 |
18 | CountDownLatch countDownLatch = new CountDownLatch(totalThread);
19 |
20 | ExecutorService executorService = Executors.newCachedThreadPool();
21 | for (int i = 0; i < totalThread; ++i) {
22 | executorService.execute(() -> {
23 | System.out.println("hello CountDownLatch.");
24 | countDownLatch.countDown();
25 | });
26 | }
27 | try {
28 | countDownLatch.await();
29 | } catch (InterruptedException e) {
30 | e.printStackTrace();
31 | }
32 | System.out.println("all come.");
33 | executorService.shutdown();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution056.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Collections;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | /**
8 | * @author: mayuan
9 | * @desc: 合并区间
10 | * @date: 2019/01/13
11 | */
12 | public class Solution056 {
13 |
14 | public List merge(List intervals) {
15 | if (null == intervals) {
16 | return intervals;
17 | }
18 |
19 | Collections.sort(intervals, (a, b) -> a.start - b.start);
20 |
21 | LinkedList result = new LinkedList<>();
22 | for (Interval e : intervals) {
23 | if (result.isEmpty() || result.getLast().end < e.start) {
24 | result.add(e);
25 | } else {
26 | result.getLast().end = Math.max(result.getLast().end, e.end);
27 | }
28 | }
29 | return result;
30 | }
31 |
32 | private class Interval {
33 | int start;
34 | int end;
35 |
36 | Interval() {
37 | start = 0;
38 | end = 0;
39 | }
40 |
41 | Interval(int s, int e) {
42 | start = s;
43 | end = e;
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution020.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * @author mayuan
7 | * @desc
8 | * @date 2018/02/08
9 | */
10 | public class Solution020 {
11 |
12 | public boolean isValid(String s) {
13 | if (null == s || (1 == (s.length() & 1))){
14 | return false;
15 | }
16 |
17 | Stack stack = new Stack<>();
18 | for (int i=0; i= points.length) {
27 | return 0;
28 | }
29 |
30 | Arrays.sort(points, (a, b) -> a[1] - b[1]);
31 | int arrowCnt = 1, arrowPos = points[0][1];
32 | for (int i = 1; i < points.length; ++i) {
33 | if (arrowPos >= points[i][0]) {
34 | continue;
35 | }
36 | ++arrowCnt;
37 | arrowPos = points[i][1];
38 | }
39 | return arrowCnt;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution540.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc:
6 | * @date: 2018/08/20
7 | */
8 | public class Solution540 {
9 | public static void main(String[] args) {
10 | int[] nums = {3, 3, 7, 7, 10, 11, 11};
11 |
12 | Solution540 test = new Solution540();
13 | System.out.println(test.singleNonDuplicate(nums));
14 | System.out.println(test.singleNonDuplicate2(nums));
15 | }
16 |
17 | public int singleNonDuplicate(int[] nums) {
18 | int ans = 0;
19 | for (int n : nums) {
20 | ans ^= n;
21 | }
22 | return ans;
23 | }
24 |
25 | public int singleNonDuplicate2(int[] nums) {
26 | int left = 0, right = nums.length - 1;
27 | while (left < right) {
28 | int mid = ((right - left) >> 1) + left;
29 | // 保证 left right mid 都在偶数位,使得查找区间大小一直都是奇数
30 | if (1 == (mid & 1)) {
31 | --mid;
32 | }
33 | if (nums[mid] == nums[mid + 1]) {
34 | left = mid + 2;
35 | } else {
36 | right = mid;
37 | }
38 | }
39 | return nums[left];
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution061.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 旋转链表
6 | * @date: 2019/01/03
7 | */
8 | public class Solution061 {
9 |
10 | public ListNode rotateRight(ListNode head, int k) {
11 | if (null == head || 0 > k) {
12 | return null;
13 | }
14 |
15 | // 获得链表的长度
16 | int cnt = 0;
17 | ListNode tmp = head;
18 | while (null != tmp) {
19 | ++cnt;
20 | tmp = tmp.next;
21 | }
22 |
23 | k %= cnt;
24 | if (0 == k) {
25 | return head;
26 | }
27 |
28 | ListNode fast = head;
29 | ListNode slow = head;
30 | for (int i = 0; i < k; ++i) {
31 | fast = fast.next;
32 | }
33 |
34 | while (null != fast.next) {
35 | fast = fast.next;
36 | slow = slow.next;
37 | }
38 |
39 | fast.next = head;
40 | head = slow.next;
41 | slow.next = null;
42 | return head;
43 | }
44 |
45 | private class ListNode {
46 | int val;
47 | ListNode next;
48 |
49 | ListNode(int x) {
50 | val = x;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/bishi/Main090402.java:
--------------------------------------------------------------------------------
1 | package bishi;
2 |
3 | import java.util.Arrays;
4 | import java.util.Scanner;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc:
9 | * @date: 2018/09/04
10 | */
11 | public class Main090402 {
12 | public static void main(String[] args) {
13 | Scanner scanner = new Scanner(System.in);
14 |
15 | int n = Integer.parseInt(scanner.nextLine());
16 | int targetTime = Integer.parseInt(scanner.nextLine());
17 | int[][] matrix = new int[n][3];
18 |
19 | for (int i = 0; i < n; ++i) {
20 | String[] temp = scanner.nextLine().split("\\s+");
21 | matrix[i][0] = Integer.parseInt(temp[0]);
22 | matrix[i][1] = Integer.parseInt(temp[1]);
23 | matrix[i][2] = Integer.parseInt(temp[2]);
24 | }
25 |
26 | Arrays.sort(matrix, (a, b) -> (a[0] - b[0]));
27 |
28 | boolean flag = false;
29 | for (int i = 0; i < n; ++i) {
30 | if (matrix[i][1] <= targetTime && targetTime <= matrix[i][2]) {
31 | flag = true;
32 | System.out.println(matrix[i][0]);
33 | }
34 | }
35 | if (!flag) {
36 | System.out.println("null");
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution009.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author mayuan
5 | * @desc
6 | * @date 2018/02/08
7 | */
8 | public class Solution009 {
9 |
10 | public boolean isPalindrome(int x) {
11 | // Special cases:
12 | // As discussed above, when x < 0, x is not a palindrome.
13 | // Also if the last digit of the number is 0, in order to be a palindrome,
14 | // the first digit of the number also needs to be 0.
15 | // Only 0 satisfy this property.
16 | if (0 > x || (0 == x % 10 && 0 != x)) {
17 | return false;
18 | }
19 |
20 | int revertedNumber = 0;
21 | while (x > revertedNumber) {
22 | revertedNumber = revertedNumber * 10 + x % 10;
23 | x /= 10;
24 | }
25 |
26 | // When the length is an odd number, we can get rid of the middle digit by revertedNumber/10
27 | // For example when the input is 12321, at the end of the while loop we get x = 12, revertedNumber = 123,
28 | // since the middle digit doesn't matter in palidrome(it will always equal to itself), we can simply get rid of it.
29 | return x == revertedNumber || x == revertedNumber / 10;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution102.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 |
7 | /**
8 | * @author: mayuan
9 | * @desc: 二叉树的层次遍历
10 | * @date: 2019/02/26
11 | */
12 | public class Solution102 {
13 | public List> levelOrder(TreeNode root) {
14 | List> ans = new ArrayList<>();
15 |
16 | if (null == root) {
17 | return ans;
18 | }
19 |
20 | levelOrder(ans, root, 0);
21 | return ans;
22 | }
23 |
24 | public void levelOrder(List> answer, TreeNode node, int depth) {
25 | if (null == node) {
26 | return;
27 | }
28 |
29 | // 遍历到当前层的第一个节点
30 | if (answer.size() <= depth) {
31 | answer.add(new LinkedList<>());
32 | }
33 | answer.get(depth).add(node.val);
34 | levelOrder(answer, node.left, depth + 1);
35 | levelOrder(answer, node.right, depth + 1);
36 | }
37 |
38 | public class TreeNode {
39 | int val;
40 | TreeNode left;
41 | TreeNode right;
42 |
43 | TreeNode(int x) {
44 | val = x;
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt03/ThreadInterrupted2.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt03;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/06/30
9 | */
10 | public class ThreadInterrupted2 {
11 | public static void main(String[] args) throws InterruptedException {
12 | Thread thread = new Thread() {
13 | @Override
14 | public void run() {
15 | while (true) {
16 | try {
17 | TimeUnit.MINUTES.sleep(1);
18 | } catch (InterruptedException e) {
19 | System.out.printf("I am be interrupted ? %s\n", isInterrupted());
20 | }
21 | }
22 | }
23 | };
24 | thread.setDaemon(true);
25 | thread.start();
26 |
27 | TimeUnit.MILLISECONDS.sleep(2);
28 | System.out.printf("Thread be interrupted ? %s\n", thread.isInterrupted());
29 | Thread.interrupted();
30 | System.out.printf("Thread be interrupted ? %s\n", thread.isInterrupted());
31 | TimeUnit.MILLISECONDS.sleep(2);
32 | System.out.printf("Thread be interrupted ? %s\n", thread.isInterrupted());
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/sfo/cpt06/Solution063.java:
--------------------------------------------------------------------------------
1 | package algorithm.sfo.cpt06;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 股票的最大利润
6 | * @date: 2018/09/25
7 | */
8 | public class Solution063 {
9 |
10 | public static void main(String[] args) {
11 | int[] numbers = {9, 11, 8, 5, 7, 12, 16, 14};
12 |
13 | final int answer = 11;
14 |
15 | System.out.println(answer == getMaxValue(numbers));
16 | }
17 |
18 | /**
19 | * 思路: 在卖出价固定时,买入价越低获得的利润越大.
20 | * 在扫描到数组中的第 i 个数字时,只要能够记住之前的 i-1 个数字中的最小值,就能够算出当前价位卖出时可能得到的最大利润.
21 | *
22 | * @param array
23 | * @return
24 | */
25 | public static int getMaxValue(int[] array) {
26 | if (null == array || 2 > array.length) {
27 | return -1;
28 | }
29 |
30 | int minNumber = array[0];
31 | int maxValue = array[1] - array[0];
32 |
33 | for (int i = 2; i < array.length; ++i) {
34 | if (array[i - 1] < minNumber) {
35 | minNumber = array[i - 1];
36 | }
37 |
38 | int current = array[i] - minNumber;
39 | if (current > maxValue) {
40 | maxValue = current;
41 | }
42 | }
43 |
44 | return maxValue;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution220.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author: mayuan
8 | * @desc: 存在重复元素 III
9 | * @date: 2019/03/02
10 | */
11 | public class Solution220 {
12 |
13 | public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
14 | if (k < 1 || t < 0) {
15 | return false;
16 | }
17 |
18 | Map map = new HashMap<>(k);
19 | for (int i = 0; i < nums.length; ++i) {
20 | long remappedNum = (long) nums[i] - Integer.MIN_VALUE;
21 | long bucket = remappedNum / ((long) t + 1);
22 |
23 | if (map.containsKey(bucket)
24 | || (map.containsKey(bucket - 1) && remappedNum - map.get(bucket - 1) <= t)
25 | || (map.containsKey(bucket + 1) && map.get(bucket + 1) - remappedNum <= t)) {
26 | return true;
27 | }
28 |
29 | if (map.size() >= k) {
30 | long lastBucket = ((long) nums[i - k] - Integer.MIN_VALUE) / ((long) t + 1);
31 | map.remove(lastBucket);
32 | }
33 | map.put(bucket, remappedNum);
34 | }
35 | return false;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution064.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 最小路径和
6 | * @date: 2018/08/22
7 | */
8 | public class Solution064 {
9 | public static void main(String[] args) {
10 | int[][] grid = {
11 | {1, 2},
12 | {5, 6},
13 | {1, 1}};
14 |
15 | Solution064 test = new Solution064();
16 | System.out.println(test.minPathSum(grid));
17 | }
18 |
19 | public int minPathSum(int[][] grid) {
20 | if (null == grid || 0 >= grid.length || 0 >= grid[0].length) {
21 | return 0;
22 | }
23 |
24 | // dp[j]代表:到第(i,j)个位置路径数字总和最小值
25 | int[] dp = new int[grid[0].length];
26 | dp[0] = grid[0][0];
27 | // 初始化第一行
28 | for (int j = 1; j < dp.length; ++j) {
29 | dp[j] = grid[0][j] + dp[j - 1];
30 | }
31 |
32 | for (int i = 1; i < grid.length; ++i) {
33 | // 当前行第一列的值为:上一行第一列的值 + 当前位置值
34 | dp[0] = dp[0] + grid[i][0];
35 | for (int j = 1; j < grid[i].length; ++j) {
36 | dp[j] = Math.min(dp[j], dp[j - 1]) + grid[i][j];
37 | }
38 | }
39 | return dp[grid[0].length - 1];
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution088.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 合并两个有序数组
6 | * @date: 2018/08/17
7 | */
8 | public class Solution088 {
9 | public static void main(String[] args) {
10 | Solution088 test = new Solution088();
11 |
12 | int[] a = new int[]{1, 2, 3, 0, 0, 0};
13 | int[] b = new int[]{2, 5, 6};
14 | test.merge(a, 3, b, 3);
15 |
16 | for (int t : a) {
17 | System.out.print(t);
18 | System.out.print(" ");
19 | }
20 | System.out.println();
21 | }
22 |
23 | public void merge(int[] nums1, int m, int[] nums2, int n) {
24 | int index1 = m - 1;
25 | int index2 = n - 1;
26 | int mergeIndex = m + n - 1;
27 |
28 | while (0 <= index1 || 0 <= index2) {
29 | if (0 > index1) {
30 | nums1[mergeIndex--] = nums2[index2--];
31 | } else if (0 > index2) {
32 | nums1[mergeIndex--] = nums1[index1--];
33 | } else if (nums1[index1] <= nums2[index2]) {
34 | nums1[mergeIndex--] = nums2[index2--];
35 | } else {
36 | nums1[mergeIndex--] = nums1[index1--];
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution107.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.LinkedList;
6 | import java.util.List;
7 |
8 | /**
9 | * @author: mayuan
10 | * @desc: 二叉树的层次遍历 II
11 | * @date: 2019/03/07
12 | */
13 | public class Solution107 {
14 |
15 | public List> levelOrderBottom(TreeNode root) {
16 | List> ans = new ArrayList<>();
17 | if (null == root) {
18 | return ans;
19 | }
20 |
21 | dfs(ans, root, 0);
22 | Collections.reverse(ans);
23 | return ans;
24 | }
25 |
26 | private void dfs(List> answer, TreeNode node, int depth) {
27 | if (null == node) {
28 | return;
29 | }
30 |
31 | if (answer.size() <= depth) {
32 | answer.add(new LinkedList<>());
33 | }
34 | answer.get(depth).add(node.val);
35 |
36 | dfs(answer, node.left, depth + 1);
37 | dfs(answer, node.right, depth + 1);
38 | }
39 |
40 | class TreeNode {
41 | int val;
42 | TreeNode left;
43 | TreeNode right;
44 |
45 | TreeNode(int x) {
46 | val = x;
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution547.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 朋友圈
6 | * @date: 2018/08/15
7 | */
8 | public class Solution547 {
9 | public static void main(String[] args) {
10 | Solution547 test = new Solution547();
11 |
12 | int[][] M = new int[][]{
13 | {1, 1, 0},
14 | {1, 1, 0},
15 | {0, 0, 1}};
16 | System.out.println(test.findCircleNum(M));
17 | }
18 |
19 | public int findCircleNum(int[][] M) {
20 | if (null == M || 0 >= M.length) {
21 | return 0;
22 | }
23 |
24 | int circleNumber = 0;
25 | boolean[] hasVisited = new boolean[M.length];
26 | for (int i = 0; i < M.length; ++i) {
27 | if (!hasVisited[i]) {
28 | dfs(M, hasVisited, i);
29 | ++circleNumber;
30 | }
31 | }
32 | return circleNumber;
33 | }
34 |
35 | private void dfs(int[][] M, boolean[] hasVisited, int i) {
36 | hasVisited[i] = true;
37 | for (int j = 0; j < M[i].length; ++j) {
38 | if (1 == M[i][j] && !hasVisited[j]) {
39 | dfs(M, hasVisited, j);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/note/MergeArray.java:
--------------------------------------------------------------------------------
1 | package algorithm.note;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 合并两个有序数组
6 | * @date: 2018/09/04
7 | */
8 | public class MergeArray {
9 | public static void main(String[] args) {
10 | int[] a = {1, 3, 5, 7, 9};
11 | int[] b = {0, 2, 4, 6, 8};
12 |
13 | int[] array = mergeArray(a, b);
14 | printArray(array);
15 | }
16 |
17 | public static int[] mergeArray(int[] a, int[] b) {
18 | int length = a.length + b.length;
19 | int[] array = new int[length];
20 |
21 | int i = 0, j = 0, k = 0;
22 | while (i < a.length && j < b.length) {
23 | if (a[i] < b[j]) {
24 | array[k++] = a[i++];
25 | } else {
26 | array[k++] = b[j++];
27 | }
28 | }
29 |
30 | while (i < a.length) {
31 | array[k++] = a[i++];
32 | }
33 | while (j < b.length) {
34 | array[k++] = b[j++];
35 | }
36 |
37 | return array;
38 | }
39 |
40 | public static void printArray(int[] array) {
41 | for (int i = 0; i < array.length; ++i) {
42 | System.out.print(array[i] + " ");
43 | }
44 | System.out.println();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/concurrent/cpt12/VolatileFoo.java:
--------------------------------------------------------------------------------
1 | package concurrent.cpt12;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | /**
6 | * @author: mayuan
7 | * @desc:
8 | * @date: 2018/07/09
9 | */
10 | public class VolatileFoo {
11 |
12 | final static int MAX = 5;
13 | static int init_value = 0;
14 |
15 | public static void main(String[] args) {
16 | new Thread(() -> {
17 | int localValue = init_value;
18 | while (localValue < MAX) {
19 | if (localValue != init_value) {
20 | System.out.println("The init_value is updated to " + init_value);
21 | localValue = init_value;
22 | }
23 | }
24 | }, "Reader").start();
25 |
26 | new Thread(() -> {
27 | int localValue = init_value;
28 | while (localValue < MAX) {
29 | System.out.println("The init_value will be changed to " + (++localValue));
30 | init_value = localValue;
31 | try {
32 | TimeUnit.SECONDS.sleep(2);
33 | } catch (InterruptedException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | }, "Updater").start();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution491.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | import java.util.HashSet;
4 | import java.util.LinkedList;
5 | import java.util.List;
6 | import java.util.Set;
7 |
8 | /**
9 | * @author: mayuan
10 | * @desc: 递增子序列
11 | * @date: 2019/03/15
12 | */
13 | public class Solution491 {
14 | public List> findSubsequences(int[] nums) {
15 | List> ans = new LinkedList<>();
16 | dfs(ans, new LinkedList<>(), nums, 0);
17 | return ans;
18 | }
19 |
20 | public void dfs(List> answer, LinkedList oneAnswer, int[] nums, int start) {
21 | if (oneAnswer.size() > 1) {
22 | answer.add(new LinkedList<>(oneAnswer));
23 | }
24 |
25 | Set set = new HashSet<>();
26 | for (int i = start; i < nums.length; ++i) {
27 | if (set.contains(nums[i])) {
28 | continue;
29 | }
30 |
31 | if (0 == oneAnswer.size() || nums[i] >= oneAnswer.peekLast()) {
32 | set.add(nums[i]);
33 | oneAnswer.add(nums[i]);
34 | dfs(answer, oneAnswer, nums, i + 1);
35 | oneAnswer.remove(oneAnswer.size() - 1);
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/sfo/cpt06/Solution05602.java:
--------------------------------------------------------------------------------
1 | package algorithm.sfo.cpt06;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 数组中仅有一个数字出现1次, 其余数字都出现了三次, 找出这个数字.
6 | * @date: 2018/09/25
7 | */
8 | public class Solution05602 {
9 |
10 | public static void main(String[] args) {
11 | int[] numbers = {1, 1, 1, 2, 2, 2, 5, 3, 3, 3};
12 |
13 | System.out.println(findAppearOnceNumber(numbers));
14 | }
15 |
16 | /**
17 | * 采用位运算的思路:将所有数字都采用二进制的表示形式,int类型采用32个bit位来表示.
18 | * 将对应的bit位相加,如果该位置的和能被3整除,则对应所求数字的该位置为0; 不能被3整除,则对应所求数字的该位置为1.
19 | *
20 | * @param array
21 | * @return
22 | */
23 | public static int findAppearOnceNumber(int[] array) {
24 | int[] bit = new int[32];
25 |
26 | for (int i = 0; i < array.length; ++i) {
27 | int bitMask = 1;
28 | for (int j = 31; j >= 0; --j) {
29 | if (0 != (array[i] & bitMask)) {
30 | ++bit[j];
31 | }
32 | bitMask = bitMask << 1;
33 | }
34 | }
35 |
36 | int result = 0;
37 | for (int i = 0; i < bit.length; ++i) {
38 | result = result << 1;
39 | result += (bit[i] % 3);
40 | }
41 |
42 | return result;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/tmop/Solution018.java:
--------------------------------------------------------------------------------
1 | package algorithm.tmop;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 有序数组的查找
6 | * 时间复杂度: O(logN)
7 | * 空间复杂度: O(1)
8 | * @date:
9 | */
10 | public class Solution018 {
11 |
12 | public static void main(String[] args) {
13 | int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
14 | final int target = 8;
15 | System.out.println("target=" + target + "的下标为:" + binarySearch(array, target));
16 | }
17 |
18 | /**
19 | * 对于有序数组,首选二分查找.
20 | * 找到元素则返回该元素的下标,未找到则返回-1
21 | *
22 | * @param array
23 | * @param target
24 | * @return
25 | */
26 | public static int binarySearch(int[] array, int target) {
27 | if (null == array || 0 >= array.length) {
28 | return -1;
29 | }
30 |
31 | int left = 0;
32 | int right = array.length - 1;
33 | while (left <= right) {
34 | int middle = left + (right - left) / 2;
35 | if (array[middle] > target) {
36 | right = middle - 1;
37 | } else if (array[middle] < target) {
38 | left = middle + 1;
39 | } else {
40 | return middle;
41 | }
42 | }
43 | return -1;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/algorithm/leetcode/Solution106.java:
--------------------------------------------------------------------------------
1 | package algorithm.leetcode;
2 |
3 | /**
4 | * @author: mayuan
5 | * @desc: 从中序与后序遍历序列构造二叉树
6 | * @date: 2019/03/06
7 | */
8 | public class Solution106 {
9 | public TreeNode buildTree(int[] inorder, int[] postorder) {
10 | return dfs(inorder, postorder, 0, inorder.length - 1, postorder.length - 1);
11 | }
12 |
13 | private TreeNode dfs(int[] inorder, int[] postorder, int inStart, int inEnd, int postEnd) {
14 | if (inStart > inEnd || postEnd < 0) {
15 | return null;
16 | }
17 |
18 | TreeNode node = new TreeNode(postorder[postEnd]);
19 | int inIndex = 0;
20 | for (int i = inEnd; i >= inStart; --i) {
21 | if (inorder[i] == node.val) {
22 | inIndex = i;
23 | break;
24 | }
25 | }
26 |
27 | node.left = dfs(inorder, postorder, inStart, inIndex - 1, postEnd - (inEnd - inIndex + 1));
28 | node.right = dfs(inorder, postorder, inIndex + 1, inEnd, postEnd - 1);
29 | return node;
30 | }
31 |
32 | private class TreeNode {
33 | int val;
34 | TreeNode left;
35 | TreeNode right;
36 |
37 | TreeNode(int x) {
38 | val = x;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------