auto commit
This commit is contained in:
parent
6c274c42eb
commit
9ff44a9016
|
@ -144,9 +144,9 @@ Google 开源项目的代码风格规范。
|
||||||
|
|
||||||
**关于贡献**
|
**关于贡献**
|
||||||
|
|
||||||
因为大部分内容是笔者一个字一个字打上去的,所有难免会有一些笔误。如果发现,可以直接在相应的文档上编辑修改。
|
因为大部分内容是笔者一个字一个字打上去的,所以难免会有一些笔误。如果发现,可以直接在相应的文档上编辑修改。
|
||||||
|
|
||||||
笔者能力有限,很多内容还不够完善。如果您希望和笔者一起完善这个仓库,可以在发表一个 Issue,表明您想要添加的内容,笔者会及时查看。
|
笔者能力有限,很多内容还不够完善。如果您希望和笔者一起完善这个仓库,可以发表一个 Issue,表明您想要添加的内容,笔者会及时查看。
|
||||||
|
|
||||||
因为不打算将这个仓库做成一个大而全的面试宝典,只希望添加一些比较通用的基础知识,或者是与 Java 和分布式相关的内容,但是不添加 Java Web 相关的内容。
|
因为不打算将这个仓库做成一个大而全的面试宝典,只希望添加一些比较通用的基础知识,或者是与 Java 和分布式相关的内容,但是不添加 Java Web 相关的内容。
|
||||||
|
|
||||||
|
|
|
@ -82,15 +82,17 @@
|
||||||
|
|
||||||
# 2. 实现 Singleton
|
# 2. 实现 Singleton
|
||||||
|
|
||||||
> [单例模式](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md)
|
[单例模式](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md)
|
||||||
|
|
||||||
# 3. 数组中重复的数字
|
# 3. 数组中重复的数字
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 7 的数组 {2, 3, 1, 0, 2, 5, 3},那么对应的输出是第一个重复的数字 2。
|
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 7 的数组 {2, 3, 1, 0, 2, 5, 3},那么对应的输出是第一个重复的数字 2。
|
||||||
|
|
||||||
要求复杂度为 O(N) + O(1),时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。
|
要求复杂度为 O(N) + O(1),也就是时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
|
@ -111,8 +113,6 @@ position-4 : (0,1,2,3,2,5) // nums[i] == nums[nums[i]], exit
|
||||||
|
|
||||||
遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复。
|
遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复。
|
||||||
|
|
||||||
复杂度:O(N) + O(1)
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public boolean duplicate(int[] nums, int length, int[] duplication) {
|
public boolean duplicate(int[] nums, int length, int[] duplication) {
|
||||||
if (nums == null || length <= 0) return false;
|
if (nums == null || length <= 0) return false;
|
||||||
|
@ -135,6 +135,8 @@ private void swap(int[] nums, int i, int j) {
|
||||||
|
|
||||||
# 4. 二维数组中的查找
|
# 4. 二维数组中的查找
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
|
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
|
||||||
|
@ -157,7 +159,7 @@ Given target = 20, return false.
|
||||||
|
|
||||||
从右上角开始查找。因为矩阵中的一个数,它左边的数都比它小,下边的数都比它大。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间。
|
从右上角开始查找。因为矩阵中的一个数,它左边的数都比它小,下边的数都比它大。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间。
|
||||||
|
|
||||||
复杂度:O(M+N) + O(1)
|
复杂度:O(M + N) + O(1)
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public boolean Find(int target, int[][] matrix) {
|
public boolean Find(int target, int[][] matrix) {
|
||||||
|
@ -175,6 +177,8 @@ public boolean Find(int target, int[][] matrix) {
|
||||||
|
|
||||||
# 5. 替换空格
|
# 5. 替换空格
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为 We Are Happy. 则经过替换之后的字符串为 We%20Are%20Happy。
|
请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为 We Are Happy. 则经过替换之后的字符串为 We%20Are%20Happy。
|
||||||
|
@ -183,9 +187,9 @@ public boolean Find(int target, int[][] matrix) {
|
||||||
|
|
||||||
在字符串尾部填充任意字符,使得字符串的长度等于字符串替换之后的长度。因为一个空格要替换成三个字符(%20),因此当遍历到一个空格时,需要在尾部填充两个任意字符。
|
在字符串尾部填充任意字符,使得字符串的长度等于字符串替换之后的长度。因为一个空格要替换成三个字符(%20),因此当遍历到一个空格时,需要在尾部填充两个任意字符。
|
||||||
|
|
||||||
令 P1 指向字符串原来的末尾位置,P2 指向字符串现在的末尾位置。P1 和 P2 从后向前遍历,当 P1 遍历到一个空格时,就需要令 P2 指向的位置依次填充 02%(注意是逆序的),否则就填充上 P1 指向字符的值。
|
令 idxOfOld 指向字符串原来的末尾位置,idxOfNew 指向字符串现在的末尾位置。idxOfOld 和 idxOfNew 从后向前遍历,当 idxOfOld 遍历到一个空格时,就需要令 idxOfNew 指向的位置依次填充 02%(注意是逆序的),否则就填充上 idxOfOld 指向字符的值。
|
||||||
|
|
||||||
从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。
|
从后向前遍是为了在改变 idxOfNew 所指向的内容时,不会影响到 idxOfOld 遍历原来字符串的内容。
|
||||||
|
|
||||||
复杂度:O(N) + O(1)
|
复杂度:O(N) + O(1)
|
||||||
|
|
||||||
|
@ -215,6 +219,8 @@ public String replaceSpace(StringBuffer str) {
|
||||||
|
|
||||||
# 6. 从尾到头打印链表
|
# 6. 从尾到头打印链表
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
输入链表的第一个节点,从尾到头反过来打印出每个结点的值。
|
输入链表的第一个节点,从尾到头反过来打印出每个结点的值。
|
||||||
|
@ -296,6 +302,8 @@ public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
|
||||||
|
|
||||||
# 7. 重建二叉树
|
# 7. 重建二叉树
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
|
根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
|
||||||
|
@ -322,8 +330,7 @@ public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int[] in, int inL, int inR) {
|
private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int[] in, int inL, int inR) {
|
||||||
if (preL == preR) return new TreeNode(pre[preL]);
|
if (preL > preR) return null;
|
||||||
if (preL > preR || inL > inR) return null;
|
|
||||||
TreeNode root = new TreeNode(pre[preL]);
|
TreeNode root = new TreeNode(pre[preL]);
|
||||||
int inIdx = inOrderNumsIdx.get(root.val);
|
int inIdx = inOrderNumsIdx.get(root.val);
|
||||||
int leftTreeSize = inIdx - inL;
|
int leftTreeSize = inIdx - inL;
|
||||||
|
@ -335,6 +342,8 @@ private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int[] in,
|
||||||
|
|
||||||
# 8. 二叉树的下一个结点
|
# 8. 二叉树的下一个结点
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
|
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
|
||||||
|
@ -366,12 +375,16 @@ public class TreeLinkNode {
|
||||||
public TreeLinkNode GetNext(TreeLinkNode pNode) {
|
public TreeLinkNode GetNext(TreeLinkNode pNode) {
|
||||||
if (pNode.right != null) {
|
if (pNode.right != null) {
|
||||||
TreeLinkNode node = pNode.right;
|
TreeLinkNode node = pNode.right;
|
||||||
while (node.left != null) node = node.left;
|
while (node.left != null) {
|
||||||
|
node = node.left;
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
} else {
|
} else {
|
||||||
while (pNode.next != null) {
|
while (pNode.next != null) {
|
||||||
TreeLinkNode parent = pNode.next;
|
TreeLinkNode parent = pNode.next;
|
||||||
if (parent.left == pNode) return parent;
|
if (parent.left == pNode) {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
pNode = pNode.next;
|
pNode = pNode.next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,9 +394,15 @@ public TreeLinkNode GetNext(TreeLinkNode pNode) {
|
||||||
|
|
||||||
# 9. 用两个栈实现队列
|
# 9. 用两个栈实现队列
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
|
## 题目描述
|
||||||
|
|
||||||
|
用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。队列中的元素为 int 类型。
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,此时先进入的元素先退出,这就是队列的顺序。
|
in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//5acf7550-86c5-4c5b-b912-8ce70ef9c34e.png" width="400"/> </div><br>
|
<div align="center"> <img src="../pics//5acf7550-86c5-4c5b-b912-8ce70ef9c34e.png" width="400"/> </div><br>
|
||||||
|
|
||||||
|
@ -410,9 +429,11 @@ public int pop() throws Exception {
|
||||||
|
|
||||||
# 10.1 斐波那契数列
|
# 10.1 斐波那契数列
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
求菲波那契数列的第 n 项。
|
求菲波那契数列的第 n 项,n <= 39。
|
||||||
|
|
||||||
<div align="center"><img src="https://latex.codecogs.com/gif.latex?f(n)=\left\{\begin{array}{rcl}0&&{n=0}\\1&&{n=1}\\f(n-1)+f(n-2)&&{n>1}\end{array}\right."/></div> <br>
|
<div align="center"><img src="https://latex.codecogs.com/gif.latex?f(n)=\left\{\begin{array}{rcl}0&&{n=0}\\1&&{n=1}\\f(n-1)+f(n-2)&&{n>1}\end{array}\right."/></div> <br>
|
||||||
|
|
||||||
|
@ -426,7 +447,7 @@ public int pop() throws Exception {
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int Fibonacci(int n) {
|
public int Fibonacci(int n) {
|
||||||
if(n <= 1) return n;
|
if (n <= 1) return n;
|
||||||
int[] fib = new int[n + 1];
|
int[] fib = new int[n + 1];
|
||||||
fib[1] = 1;
|
fib[1] = 1;
|
||||||
for (int i = 2; i <= n; i++) {
|
for (int i = 2; i <= n; i++) {
|
||||||
|
@ -440,7 +461,7 @@ public int Fibonacci(int n) {
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int Fibonacci(int n) {
|
public int Fibonacci(int n) {
|
||||||
if(n <= 1) return n;
|
if (n <= 1) return n;
|
||||||
int pre2 = 0, pre1 = 1;
|
int pre2 = 0, pre1 = 1;
|
||||||
int fib = 0;
|
int fib = 0;
|
||||||
for (int i = 2; i <= n; i++) {
|
for (int i = 2; i <= n; i++) {
|
||||||
|
@ -460,7 +481,7 @@ public class Solution {
|
||||||
public Solution() {
|
public Solution() {
|
||||||
fib[1] = 1;
|
fib[1] = 1;
|
||||||
fib[2] = 2;
|
fib[2] = 2;
|
||||||
for(int i = 2; i < fib.length; i++) {
|
for (int i = 2; i < fib.length; i++) {
|
||||||
fib[i] = fib[i - 1] + fib[i - 2];
|
fib[i] = fib[i - 1] + fib[i - 2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,6 +493,8 @@ public class Solution {
|
||||||
|
|
||||||
# 10.2 跳台阶
|
# 10.2 跳台阶
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
|
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
|
||||||
|
@ -511,27 +534,31 @@ public int JumpFloor(int n) {
|
||||||
|
|
||||||
# 10.3 变态跳台阶
|
# 10.3 变态跳台阶
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级……它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
|
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int JumpFloorII(int n) {
|
public int JumpFloorII(int target) {
|
||||||
int[] dp = new int[n];
|
int[] dp = new int[target];
|
||||||
Arrays.fill(dp, 1);
|
Arrays.fill(dp, 1);
|
||||||
for(int i = 1; i < n; i++) {
|
for (int i = 1; i < target; i++) {
|
||||||
for(int j = 0; j < i; j++) {
|
for (int j = 0; j < i; j++) {
|
||||||
dp[i] += dp[j];
|
dp[i] += dp[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dp[n - 1];
|
return dp[target - 1];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# 10.4 矩形覆盖
|
# 10.4 矩形覆盖
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法?
|
我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法?
|
||||||
|
@ -571,30 +598,17 @@ public int RectCover(int n) {
|
||||||
|
|
||||||
# 11. 旋转数组的最小数字
|
# 11. 旋转数组的最小数字
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 {3, 4, 5, 1, 2} 为 {1, 2, 3, 4, 5} 的一个旋转,该数组的最小值为 1。NOTE:给出的所有元素都大于 0,若数组大小为 0,请返回 0。
|
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组 {3, 4, 5, 1, 2} 为 {1, 2, 3, 4, 5} 的一个旋转,该数组的最小值为 1。NOTE:给出的所有元素都大于 0,若数组大小为 0,请返回 0。
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
### 分治
|
当 nums[m] <= nums[h] 的情况下,说明解在 [l, m] 之间,此时令 h = m;否则解在 [m + 1, h] 之间,令 l = m + 1。
|
||||||
|
|
||||||
复杂度:O(logN) + O(1),其实空间复杂度不止 O(1),因为分治使用了递归栈,用到了额外的空间,如果对空间有要求就不能用这种方法。
|
因为 h 的赋值表达式为 h = m,因此循环体的循环条件应该为 l < h,详细解释请见 [Leetcode 题解](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3.md#%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE)。
|
||||||
|
|
||||||
```java
|
|
||||||
public int minNumberInRotateArray(int[] nums) {
|
|
||||||
return minNumberInRotateArray(nums, 0, nums.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int minNumberInRotateArray(int[] nums, int first, int last) {
|
|
||||||
if (nums[first] < nums[last]) return nums[first];
|
|
||||||
if (first == last) return nums[first];
|
|
||||||
int mid = first + (last - first) / 2;
|
|
||||||
return Math.min(minNumberInRotateArray(nums, first, mid), minNumberInRotateArray(nums, mid + 1, last));
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 二分查找
|
|
||||||
|
|
||||||
复杂度:O(logN) + O(1)
|
复杂度:O(logN) + O(1)
|
||||||
|
|
||||||
|
@ -602,11 +616,10 @@ private int minNumberInRotateArray(int[] nums, int first, int last) {
|
||||||
public int minNumberInRotateArray(int[] nums) {
|
public int minNumberInRotateArray(int[] nums) {
|
||||||
if (nums.length == 0) return 0;
|
if (nums.length == 0) return 0;
|
||||||
int l = 0, h = nums.length - 1;
|
int l = 0, h = nums.length - 1;
|
||||||
while (nums[l] >= nums[h]) {
|
while (l < h) {
|
||||||
if (h - l == 1) return nums[h];
|
int m = l + (h - l) / 2;
|
||||||
int mid = l + (h - l) / 2;
|
if (nums[m] <= nums[h]) h = m;
|
||||||
if (nums[mid] >= nums[l]) l = mid;
|
else l = m + 1;
|
||||||
else h = mid;
|
|
||||||
}
|
}
|
||||||
return nums[l];
|
return nums[l];
|
||||||
}
|
}
|
||||||
|
@ -614,6 +627,8 @@ public int minNumberInRotateArray(int[] nums) {
|
||||||
|
|
||||||
# 12. 矩阵中的路径
|
# 12. 矩阵中的路径
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
|
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
|
||||||
|
@ -670,6 +685,8 @@ private char[][] buildMatrix(char[] array) {
|
||||||
|
|
||||||
# 13. 机器人的运动范围
|
# 13. 机器人的运动范围
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/6e5207314b5241fb83f2329e89fdecc8?tpId=13&tqId=11219&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。例如,当 k 为 18 时,机器人能够进入方格(35, 37),因为 3+5+3+7=18。但是,它不能进入方格(35, 38),因为 3+5+3+8=19。请问该机器人能够达到多少个格子?
|
地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。例如,当 k 为 18 时,机器人能够进入方格(35, 37),因为 3+5+3+7=18。但是,它不能进入方格(35, 38),因为 3+5+3+8=19。请问该机器人能够达到多少个格子?
|
||||||
|
@ -695,12 +712,12 @@ public int movingCount(int threshold, int rows, int cols) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dfs(boolean[][] hasVisited, int r, int c) {
|
private void dfs(boolean[][] hasVisited, int r, int c) {
|
||||||
if (r < 0 || r >= this.rows || c < 0 || c >= this.cols) return;
|
if (r < 0 || r >= rows || c < 0 || c >= cols) return;
|
||||||
if (hasVisited[r][c]) return;
|
if (hasVisited[r][c]) return;
|
||||||
hasVisited[r][c] = true;
|
hasVisited[r][c] = true;
|
||||||
if (this.digitSum[r][c] > this.threshold) return;
|
if (digitSum[r][c] > threshold) return;
|
||||||
this.cnt++;
|
this.cnt++;
|
||||||
for (int i = 0; i < this.next.length; i++) {
|
for (int i = 0; i < next.length; i++) {
|
||||||
dfs(hasVisited, r + next[i][0], c + next[i][1]);
|
dfs(hasVisited, r + next[i][0], c + next[i][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,10 +731,10 @@ private void initDigitSum() {
|
||||||
n /= 10;
|
n /= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.digitSum = new int[rows][cols];
|
digitSum = new int[rows][cols];
|
||||||
for (int i = 0; i < this.rows; i++) {
|
for (int i = 0; i < rows; i++) {
|
||||||
for (int j = 0; j < this.cols; j++) {
|
for (int j = 0; j < cols; j++) {
|
||||||
this.digitSum[i][j] = digitSumOne[i] + digitSumOne[j];
|
digitSum[i][j] = digitSumOne[i] + digitSumOne[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -725,16 +742,20 @@ private void initDigitSum() {
|
||||||
|
|
||||||
# 14. 剪绳子
|
# 14. 剪绳子
|
||||||
|
|
||||||
|
[Leetcode](https://leetcode.com/problems/integer-break/description/)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
把一根绳子剪成多段,并且使得每段的长度乘积最大。
|
把一根绳子剪成多段,并且使得每段的长度乘积最大。
|
||||||
|
|
||||||
|
For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
### 动态规划解法
|
### 动态规划解法
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int maxProductAfterCutting(int n) {
|
public int integerBreak(int n) {
|
||||||
int[] dp = new int[n + 1];
|
int[] dp = new int[n + 1];
|
||||||
dp[1] = 1;
|
dp[1] = 1;
|
||||||
for (int i = 2; i <= n; i++) {
|
for (int i = 2; i <= n; i++) {
|
||||||
|
@ -753,8 +774,8 @@ public int maxProductAfterCutting(int n) {
|
||||||
证明:当 n >= 5 时,3(n - 3) - 2(n - 2) = n - 5 >= 0。因此把长度大于 5 的绳子切成两段,令其中一段长度为 3 可以使得两段的乘积最大。
|
证明:当 n >= 5 时,3(n - 3) - 2(n - 2) = n - 5 >= 0。因此把长度大于 5 的绳子切成两段,令其中一段长度为 3 可以使得两段的乘积最大。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int maxProductAfterCutting(int n) {
|
public int integerBreak(int n) {
|
||||||
if (n < 2) return 0;
|
if (n < 2) return 0;
|
||||||
if (n == 2) return 1;
|
if (n == 2) return 1;
|
||||||
if (n == 3) return 2;
|
if (n == 3) return 2;
|
||||||
int timesOf3 = n / 3;
|
int timesOf3 = n / 3;
|
||||||
|
@ -766,6 +787,8 @@ public int maxProductAfterCutting(int n) {
|
||||||
|
|
||||||
# 15. 二进制中 1 的个数
|
# 15. 二进制中 1 的个数
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
输入一个整数,输出该数二进制表示中 1 的个数。
|
输入一个整数,输出该数二进制表示中 1 的个数。
|
||||||
|
@ -803,6 +826,8 @@ public int NumberOf1(int n) {
|
||||||
|
|
||||||
# 16. 数值的整数次方
|
# 16. 数值的整数次方
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00?tpId=13&tqId=11165&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
给定一个 double 类型的浮点数 base 和 int 类型的整数 exponent。求 base 的 exponent 次方。
|
给定一个 double 类型的浮点数 base 和 int 类型的整数 exponent。求 base 的 exponent 次方。
|
||||||
|
@ -817,16 +842,16 @@ public int NumberOf1(int n) {
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public double Power(double base, int exponent) {
|
public double Power(double base, int exponent) {
|
||||||
if (exponent == 0) return 1;
|
if(exponent == 0) return 1;
|
||||||
if (exponent == 1) return base;
|
if(exponent == 1) return base;
|
||||||
boolean isNegative = false;
|
boolean isNegative = false;
|
||||||
if (exponent < 0) {
|
if(exponent < 0) {
|
||||||
exponent = -exponent;
|
exponent = -exponent;
|
||||||
isNegative = true;
|
isNegative = true;
|
||||||
}
|
}
|
||||||
double pow = Power(base * base, exponent / 2);
|
double pow = Power(base * base , exponent / 2);
|
||||||
if (exponent % 2 != 0) pow = pow * base;
|
if(exponent % 2 != 0) pow = pow * base;
|
||||||
return isNegative ? (1 / pow) : pow;
|
return isNegative ? 1 / pow : pow;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -844,7 +869,7 @@ public double Power(double base, int exponent) {
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public void print1ToMaxOfNDigits(int n) {
|
public void print1ToMaxOfNDigits(int n) {
|
||||||
if (n < 0) return;
|
if (n <= 0) return;
|
||||||
char[] number = new char[n];
|
char[] number = new char[n];
|
||||||
print1ToMaxOfNDigits(number, -1);
|
print1ToMaxOfNDigits(number, -1);
|
||||||
}
|
}
|
||||||
|
@ -872,7 +897,7 @@ private void printNumber(char[] number) {
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,令该节点指向下下个节点,然后删除下一个节点,时间复杂度为 O(1)。
|
① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//41392d76-dd1d-4712-85d9-e8bb46b04a2d.png" width="600"/> </div><br>
|
<div align="center"> <img src="../pics//41392d76-dd1d-4712-85d9-e8bb46b04a2d.png" width="600"/> </div><br>
|
||||||
|
|
||||||
|
@ -901,6 +926,8 @@ public ListNode deleteNode(ListNode head, ListNode tobeDelete) {
|
||||||
|
|
||||||
# 18.2 删除链表中重复的结点
|
# 18.2 删除链表中重复的结点
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId=13&tqId=11209&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
<div align="center"> <img src="../pics//8433fbb2-c35c-45ef-831d-e3ca42aebd51.png" width="500"/> </div><br>
|
<div align="center"> <img src="../pics//8433fbb2-c35c-45ef-831d-e3ca42aebd51.png" width="500"/> </div><br>
|
||||||
|
@ -923,23 +950,26 @@ public ListNode deleteDuplication(ListNode pHead) {
|
||||||
|
|
||||||
# 19. 正则表达式匹配
|
# 19. 正则表达式匹配
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/45327ae22b7b413ea21df13ee7d6429c?tpId=13&tqId=11205&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
请实现一个函数用来匹配包括 '.' 和 '\*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '\*' 表示它前面的字符可以出现任意次(包含 0 次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab\*ac\*a" 匹配,但是与 "aa.a" 和 "ab\*a" 均不匹配。
|
请实现一个函数用来匹配包括 '.' 和 '\*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '\*' 表示它前面的字符可以出现任意次(包含 0 次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab\*ac\*a" 匹配,但是与 "aa.a" 和 "ab\*a" 均不匹配。
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
应该注意到,'.' 是用来当做一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。
|
应该注意到,'.' 是用来当做一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1];
|
if p.charAt(j) == s.charAt(i) : then dp[i][j] = dp[i-1][j-1];
|
||||||
p.charAt(j) == '.' : dp[i][j] = dp[i-1][j-1];
|
if p.charAt(j) == '.' : then dp[i][j] = dp[i-1][j-1];
|
||||||
p.charAt(j) == '*' :
|
if p.charAt(j) == '*' :
|
||||||
p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //a* only counts as empty
|
if p.charAt(j-1) != s.charAt(i) : then dp[i][j] = dp[i][j-2] // a* only counts as empty
|
||||||
p.charAt(j-1) == s.charAt(i) or p.charAt(i-1) == '.':
|
if p.charAt(j-1) == s.charAt(i)
|
||||||
dp[i][j] = dp[i-1][j] // a* counts as multiple a
|
or p.charAt(i-1) == '.' :
|
||||||
or dp[i][j] = dp[i][j-1] // a* counts as single a
|
then dp[i][j] = dp[i-1][j] // a* counts as multiple a
|
||||||
or dp[i][j] = dp[i][j-2] // a* counts as empty
|
or dp[i][j] = dp[i][j-1] // a* counts as single a
|
||||||
|
or dp[i][j] = dp[i][j-2] // a* counts as empty
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
@ -971,6 +1001,8 @@ public boolean match(char[] str, char[] pattern) {
|
||||||
|
|
||||||
# 20. 表示数值的字符串
|
# 20. 表示数值的字符串
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/6f8c901d091949a5837e24bb82a731f2?tpId=13&tqId=11206&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串 "+100","5e2","-123","3.1416" 和 "-1E-16" 都表示数值。 但是 "12e","1a3.14","1.2.3","+-5" 和 "12e+4.3" 都不是。
|
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串 "+100","5e2","-123","3.1416" 和 "-1E-16" 都表示数值。 但是 "12e","1a3.14","1.2.3","+-5" 和 "12e+4.3" 都不是。
|
||||||
|
@ -985,34 +1017,14 @@ public boolean isNumeric(char[] str) {
|
||||||
|
|
||||||
# 21. 调整数组顺序使奇数位于偶数前面
|
# 21. 调整数组顺序使奇数位于偶数前面
|
||||||
|
|
||||||
|
[NowCoder](https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593?tpId=13&tqId=11166&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||||
|
|
||||||
## 题目描述
|
## 题目描述
|
||||||
|
|
||||||
保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。
|
保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。
|
||||||
|
|
||||||
## 解题思路
|
## 解题思路
|
||||||
|
|
||||||
复杂度:O(N<sup>2</sup>) + O(1)
|
|
||||||
|
|
||||||
```java
|
|
||||||
public void reOrderArray(int[] nums) {
|
|
||||||
int n = nums.length;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (nums[i] % 2 == 0) {
|
|
||||||
int nextOddIdx = i + 1;
|
|
||||||
while (nextOddIdx < n && nums[nextOddIdx] % 2 == 0) nextOddIdx++;
|
|
||||||
if (nextOddIdx == n) break;
|
|
||||||
int nextOddVal = nums[nextOddIdx];
|
|
||||||
for (int j = nextOddIdx; j > i; j--) {
|
|
||||||
nums[j] = nums[j - 1];
|
|
||||||
}
|
|
||||||
nums[i] = nextOddVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
复杂度:O(N) + O(N)
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public void reOrderArray(int[] nums) {
|
public void reOrderArray(int[] nums) {
|
||||||
int oddCnt = 0;
|
int oddCnt = 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user