|
1 | 1 | <!-- GFM-TOC --> |
| 2 | +* [1. 前言](#1-前言) |
2 | 3 | * [2. 实现 Singleton](#2-实现-singleton) |
3 | 4 | * [3. 数组中重复的数字](#3-数组中重复的数字) |
4 | 5 | * [4. 二维数组中的查找](#4-二维数组中的查找) |
|
80 | 81 | <!-- GFM-TOC --> |
81 | 82 |
|
82 | 83 |
|
| 84 | +# 1. 前言 |
| 85 | + |
| 86 | +本文的绘图可通过以下途径免费获得并使用: |
| 87 | + |
| 88 | +- [ProcessOn](https://www.processon.com/view/5a3e4c7be4b0909c1aa18b49) |
| 89 | +- [DrawIO](https://drive.google.com/file/d/1nSSCpPUC05MFoeFuf_aeTtkm7dG5-bJ1/view?usp=sharing) |
| 90 | + |
83 | 91 | # 2. 实现 Singleton |
84 | 92 |
|
85 | 93 | [单例模式](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md) |
@@ -170,7 +178,7 @@ Given target = 20, return false. |
170 | 178 |
|
171 | 179 | 当前元素的查找区间为左下角的所有元素,例如元素 12 的查找区间如下: |
172 | 180 |
|
173 | | -<div align="center"> <img src="../pics//026d3cb4-67f7-4a83-884d-8032f57ec446.png" width="250"/> </div><br> |
| 181 | +<div align="center"> <img src="../pics//f94389e9-55b1-4f49-9d37-00ed05900ae0.png" width="250"/> </div><br> |
174 | 182 |
|
175 | 183 | 复杂度:O(M + N) + O(1) |
176 | 184 |
|
@@ -456,7 +464,7 @@ public int pop() throws Exception { |
456 | 464 |
|
457 | 465 | 如果使用递归求解,会重复计算一些子问题。例如,计算 f(10) 需要计算 f(9) 和 f(8),计算 f(9) 需要计算 f(8) 和 f(7),可以看到 f(8) 被重复计算了。 |
458 | 466 |
|
459 | | -<div align="center"> <img src="../pics//a0df8edc-581b-4977-95c2-d7025795b899.png" width="300"/> </div><br> |
| 467 | +<div align="center"> <img src="../pics//faecea49-9974-40db-9821-c8636137df61.jpg" width="300"/> </div><br> |
460 | 468 |
|
461 | 469 | 递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 |
462 | 470 |
|
@@ -941,11 +949,11 @@ private void printNumber(char[] number) { |
941 | 949 |
|
942 | 950 | ① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。 |
943 | 951 |
|
944 | | -<div align="center"> <img src="../pics//41392d76-dd1d-4712-85d9-e8bb46b04a2d.png" width="600"/> </div><br> |
| 952 | +<div align="center"> <img src="../pics//27ff9548-edb6-4465-92c8-7e6386e0b185.png" width="600"/> </div><br> |
945 | 953 |
|
946 | 954 | ② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。 |
947 | 955 |
|
948 | | -<div align="center"> <img src="../pics//db4921d4-184b-48ba-a3cf-1d1141e3ba2d.png" width="600"/> </div><br> |
| 956 | +<div align="center"> <img src="../pics//280f7728-594f-4811-a03a-fa8d32c013da.png" width="600"/> </div><br> |
949 | 957 |
|
950 | 958 | 综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。 |
951 | 959 |
|
@@ -1103,7 +1111,7 @@ public void reOrderArray(int[] nums) { |
1103 | 1111 |
|
1104 | 1112 | 设链表的长度为 N。设两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到 N - K 个节点处,该位置就是倒数第 K 个节点。 |
1105 | 1113 |
|
1106 | | -<div align="center"> <img src="../pics//207c1801-2335-4b1b-b65c-126a0ba966cb.png" width="500"/> </div><br> |
| 1114 | +<div align="center"> <img src="../pics//ea2304ce-268b-4238-9486-4d8f8aea8ca4.png" width="500"/> </div><br> |
1107 | 1115 |
|
1108 | 1116 | ```java |
1109 | 1117 | public ListNode FindKthToTail(ListNode head, int k) |
@@ -1140,7 +1148,7 @@ public ListNode FindKthToTail(ListNode head, int k) |
1140 | 1148 |
|
1141 | 1149 | 在相遇点,slow 要到环的入口点还需要移动 z 个节点,如果让 fast 重新从头开始移动,并且速度变为每次移动一个节点,那么它到环入口点还需要移动 x 个节点。在上面已经推导出 x=z,因此 fast 和 slow 将在环入口点相遇。 |
1142 | 1150 |
|
1143 | | -<div align="center"> <img src="../pics//71363383-2d06-4c63-8b72-c01c2186707d.png" width="600"/> </div><br> |
| 1151 | +<div align="center"> <img src="../pics//2858f8ad-aedb-45a5-a706-e98c96d690fa.jpg" width="600"/> </div><br> |
1144 | 1152 |
|
1145 | 1153 | ```java |
1146 | 1154 | public ListNode EntryNodeOfLoop(ListNode pHead) |
@@ -1346,7 +1354,7 @@ boolean isSymmetrical(TreeNode t1, TreeNode t2) |
1346 | 1354 |
|
1347 | 1355 | 下图的矩阵顺时针打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 |
1348 | 1356 |
|
1349 | | -<div align="center"> <img src="../pics//0f373947-c68f-45b4-a59e-086154745ac5.png" width="300"/> </div><br> |
| 1357 | +<div align="center"> <img src="../pics//6539b9a4-2b24-4d10-8c94-2eb5aba1e296.png" width="300"/> </div><br> |
1350 | 1358 |
|
1351 | 1359 | ## 解题思路 |
1352 | 1360 |
|
@@ -1632,6 +1640,19 @@ private void backtracking(TreeNode node, int target, ArrayList<Integer> path) |
1632 | 1640 |
|
1633 | 1641 | 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 head。 |
1634 | 1642 |
|
| 1643 | +```java |
| 1644 | +public class RandomListNode |
| 1645 | +{ |
| 1646 | + int label; |
| 1647 | + RandomListNode next = null; |
| 1648 | + RandomListNode random = null; |
| 1649 | + |
| 1650 | + RandomListNode(int label) { |
| 1651 | + this.label = label; |
| 1652 | + } |
| 1653 | +} |
| 1654 | +``` |
| 1655 | + |
1635 | 1656 | <div align="center"> <img src="../pics//a01d1516-8168-461a-a24b-620b9cfc40f4.png" width="300"/> </div><br> |
1636 | 1657 |
|
1637 | 1658 | ## 解题思路 |
@@ -1812,7 +1833,7 @@ private void backtracking(char[] chars, boolean[] hasUsed, StringBuilder s) |
1812 | 1833 |
|
1813 | 1834 | 多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(N)。 |
1814 | 1835 |
|
1815 | | -使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素不相等时,令 cnt--。如果前面查找了 i 个元素,且 cnt == 0 ,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。 |
| 1836 | +使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素不相等时,令 cnt--。如果前面查找了 i 个元素,且 cnt == 0,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。 |
1816 | 1837 |
|
1817 | 1838 | ```java |
1818 | 1839 | public int MoreThanHalfNum_Solution(int[] nums) |
@@ -1916,7 +1937,7 @@ public ArrayList<Integer> GetLeastNumbers_Solution(int[] nums, int k) |
1916 | 1937 | if (maxHeap.size() > k) |
1917 | 1938 | maxHeap.poll(); |
1918 | 1939 | } |
1919 | | - return new ArrayList<>(maxHeap) ; |
| 1940 | + return new ArrayList<>(maxHeap); |
1920 | 1941 | } |
1921 | 1942 | ``` |
1922 | 1943 |
|
@@ -1997,7 +2018,7 @@ public char FirstAppearingOnce() |
1997 | 2018 |
|
1998 | 2019 | ## 题目描述 |
1999 | 2020 |
|
2000 | | -{6,-3,-2,7,-15,1,2,2},连续子数组的最大和为 8(从第 0 个开始,到第 3 个为止)。 |
| 2021 | +{6, -3, -2, 7, -15, 1, 2, 2},连续子数组的最大和为 8(从第 0 个开始,到第 3 个为止)。 |
2001 | 2022 |
|
2002 | 2023 | ## 解题思路 |
2003 | 2024 |
|
|
0 commit comments