mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-11 13:00:22 +08:00
Merge branch 'youngyangyang04:master' into master
This commit is contained in:
@ -808,7 +808,93 @@ func strStr(haystack string, needle string) int {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
JavaScript版本
|
||||||
|
|
||||||
|
> 前缀表统一减一
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* @param {string} haystack
|
||||||
|
* @param {string} needle
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
var strStr = function (haystack, needle) {
|
||||||
|
if (needle.length === 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const getNext = (needle) => {
|
||||||
|
let next = [];
|
||||||
|
let j = -1;
|
||||||
|
next.push(j);
|
||||||
|
|
||||||
|
for (let i = 1; i < needle.length; ++i) {
|
||||||
|
while (j >= 0 && needle[i] !== needle[j + 1])
|
||||||
|
j = next[j];
|
||||||
|
if (needle[i] === needle[j + 1])
|
||||||
|
j++;
|
||||||
|
next.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = getNext(needle);
|
||||||
|
let j = -1;
|
||||||
|
for (let i = 0; i < haystack.length; ++i) {
|
||||||
|
while (j >= 0 && haystack[i] !== needle[j + 1])
|
||||||
|
j = next[j];
|
||||||
|
if (haystack[i] === needle[j + 1])
|
||||||
|
j++;
|
||||||
|
if (j === needle.length - 1)
|
||||||
|
return (i - needle.length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 前缀表统一不减一
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* @param {string} haystack
|
||||||
|
* @param {string} needle
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
var strStr = function (haystack, needle) {
|
||||||
|
if (needle.length === 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const getNext = (needle) => {
|
||||||
|
let next = [];
|
||||||
|
let j = 0;
|
||||||
|
next.push(j);
|
||||||
|
|
||||||
|
for (let i = 1; i < needle.length; ++i) {
|
||||||
|
while (j > 0 && needle[i] !== needle[j])
|
||||||
|
j = next[j - 1];
|
||||||
|
if (needle[i] === needle[j])
|
||||||
|
j++;
|
||||||
|
next.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = getNext(needle);
|
||||||
|
let j = 0;
|
||||||
|
for (let i = 0; i < haystack.length; ++i) {
|
||||||
|
while (j > 0 && haystack[i] !== needle[j])
|
||||||
|
j = next[j - 1];
|
||||||
|
if (haystack[i] === needle[j])
|
||||||
|
j++;
|
||||||
|
if (j === needle.length)
|
||||||
|
return (i - needle.length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,6 +99,24 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
class Solution {
|
||||||
|
public void nextPermutation(int[] nums) {
|
||||||
|
for (int i = nums.length - 1; i >= 0; i--) {
|
||||||
|
for (int j = nums.length - 1; j > i; j--) {
|
||||||
|
if (nums[j] > nums[i]) {
|
||||||
|
// 交换
|
||||||
|
int temp = nums[i];
|
||||||
|
nums[i] = nums[j];
|
||||||
|
nums[j] = temp;
|
||||||
|
// [i + 1, nums.length) 内元素升序排序
|
||||||
|
Arrays.sort(nums, i + 1, nums.length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Arrays.sort(nums); // 不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
如果数组中不存在目标值 target,返回 [-1, -1]。
|
如果数组中不存在目标值 target,返回 [-1, -1]。
|
||||||
|
|
||||||
进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
|
进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
|
||||||
|
|
||||||
|
|
||||||
示例 1:
|
示例 1:
|
||||||
* 输入:nums = [5,7,7,8,8,10], target = 8
|
* 输入:nums = [5,7,7,8,8,10], target = 8
|
||||||
@ -173,8 +173,105 @@ private:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
class Solution {
|
||||||
|
int[] searchRange(int[] nums, int target) {
|
||||||
|
int leftBorder = getLeftBorder(nums, target);
|
||||||
|
int rightBorder = getRightBorder(nums, target);
|
||||||
|
// 情况一
|
||||||
|
if (leftBorder == -2 || rightBorder == -2) return new int[]{-1, -1};
|
||||||
|
// 情况三
|
||||||
|
if (rightBorder - leftBorder > 1) return new int[]{leftBorder + 1, rightBorder - 1};
|
||||||
|
// 情况二
|
||||||
|
return new int[]{-1, -1};
|
||||||
|
}
|
||||||
|
|
||||||
|
int getRightBorder(int[] nums, int target) {
|
||||||
|
int left = 0;
|
||||||
|
int right = nums.length - 1;
|
||||||
|
int rightBorder = -2; // 记录一下rightBorder没有被赋值的情况
|
||||||
|
while (left <= right) {
|
||||||
|
int middle = left + ((right - left) / 2);
|
||||||
|
if (nums[middle] > target) {
|
||||||
|
right = middle - 1;
|
||||||
|
} else { // 寻找右边界,nums[middle] == target的时候更新left
|
||||||
|
left = middle + 1;
|
||||||
|
rightBorder = left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rightBorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLeftBorder(int[] nums, int target) {
|
||||||
|
int left = 0;
|
||||||
|
int right = nums.length - 1;
|
||||||
|
int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
|
||||||
|
while (left <= right) {
|
||||||
|
int middle = left + ((right - left) / 2);
|
||||||
|
if (nums[middle] >= target) { // 寻找左边界,nums[middle] == target的时候更新right
|
||||||
|
right = middle - 1;
|
||||||
|
leftBorder = right;
|
||||||
|
} else {
|
||||||
|
left = middle + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return leftBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 解法2
|
||||||
|
// 1、首先,在 nums 数组中二分查找 target;
|
||||||
|
// 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
|
||||||
|
// 3、如果二分查找成功,则 binarySearch 返回 nums 中值为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
|
||||||
|
|
||||||
|
class Solution {
|
||||||
|
public int[] searchRange(int[] nums, int target) {
|
||||||
|
int index = binarySearch(nums, target); // 二分查找
|
||||||
|
|
||||||
|
if (index == -1) { // nums 中不存在 target,直接返回 {-1, -1}
|
||||||
|
return new int[] {-1, -1}; // 匿名数组
|
||||||
|
}
|
||||||
|
// nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
|
||||||
|
int left = index;
|
||||||
|
int right = index;
|
||||||
|
// 向左滑动,找左边界
|
||||||
|
while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
|
||||||
|
left--;
|
||||||
|
}
|
||||||
|
// 向左滑动,找右边界
|
||||||
|
while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。
|
||||||
|
right++;
|
||||||
|
}
|
||||||
|
return new int[] {left, right};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二分查找
|
||||||
|
* @param nums
|
||||||
|
* @param target
|
||||||
|
*/
|
||||||
|
public int binarySearch(int[] nums, int target) {
|
||||||
|
int left = 0;
|
||||||
|
int right = nums.length - 1; // 不变量:左闭右闭区间
|
||||||
|
|
||||||
|
while (left <= right) { // 不变量:左闭右闭区间
|
||||||
|
int mid = left + (right - left) / 2;
|
||||||
|
if (nums[mid] == target) {
|
||||||
|
return mid;
|
||||||
|
} else if (nums[mid] < target) {
|
||||||
|
left = mid + 1;
|
||||||
|
} else {
|
||||||
|
right = mid - 1; // 不变量:左闭右闭区间
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // 不存在
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -196,4 +293,3 @@ private:
|
|||||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +138,35 @@ class Solution:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
```Go
|
||||||
|
// solution
|
||||||
|
// 1, dp
|
||||||
|
// 2, 贪心
|
||||||
|
|
||||||
|
func maxSubArray(nums []int) int {
|
||||||
|
n := len(nums)
|
||||||
|
// 这里的dp[i] 表示,最大的连续子数组和,包含num[i] 元素
|
||||||
|
dp := make([]int,n)
|
||||||
|
// 初始化,由于dp 状态转移方程依赖dp[0]
|
||||||
|
dp[0] = nums[0]
|
||||||
|
// 初始化最大的和
|
||||||
|
mx := nums[0]
|
||||||
|
for i:=1;i<n;i++ {
|
||||||
|
// 这里的状态转移方程就是:求最大和
|
||||||
|
// 会面临2种情况,一个是带前面的和,一个是不带前面的和
|
||||||
|
dp[i] = max(dp[i-1]+nums[i],nums[i])
|
||||||
|
mx = max(mx,dp[i])
|
||||||
|
}
|
||||||
|
return mx
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(a,b int) int{
|
||||||
|
if a>b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -654,43 +654,68 @@ class Solution {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
105.从前序与中序遍历序列构造二叉树
|
105.从前序与中序遍历序列构造二叉树
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Definition for a binary tree node.
|
|
||||||
# class TreeNode:
|
|
||||||
# def __init__(self, val=0, left=None, right=None):
|
|
||||||
# self.val = val
|
|
||||||
# self.left = left
|
|
||||||
# self.right = right
|
|
||||||
//递归法
|
|
||||||
class Solution:
|
class Solution:
|
||||||
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
|
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
|
||||||
if not preorder: return None //特殊情况
|
# 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
|
||||||
root = TreeNode(preorder[0]) //新建父节点
|
if not preorder:
|
||||||
p=inorder.index(preorder[0]) //找到父节点在中序遍历的位置(因为没有重复的元素,才可以这样找)
|
return None
|
||||||
root.left = self.buildTree(preorder[1:p+1],inorder[:p]) //注意左节点时分割中序数组和前续数组的开闭环
|
|
||||||
root.right = self.buildTree(preorder[p+1:],inorder[p+1:]) //分割中序数组和前续数组
|
# 第二步: 前序遍历的第一个就是当前的中间节点.
|
||||||
return root
|
root_val = preorder[0]
|
||||||
|
root = TreeNode(root_val)
|
||||||
|
|
||||||
|
# 第三步: 找切割点.
|
||||||
|
separator_idx = inorder.index(root_val)
|
||||||
|
|
||||||
|
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
|
||||||
|
inorder_left = inorder[:separator_idx]
|
||||||
|
inorder_right = inorder[separator_idx + 1:]
|
||||||
|
|
||||||
|
# 第五步: 切割preorder数组. 得到preorder数组的左,右半边.
|
||||||
|
# ⭐️ 重点1: 中序数组大小一定跟前序数组大小是相同的.
|
||||||
|
preorder_left = preorder[1:1 + len(inorder_left)]
|
||||||
|
preorder_right = preorder[1 + len(inorder_left):]
|
||||||
|
|
||||||
|
# 第六步: 递归
|
||||||
|
root.left = self.buildTree(preorder_left, inorder_left)
|
||||||
|
root.right = self.buildTree(preorder_right, inorder_right)
|
||||||
|
|
||||||
|
return root
|
||||||
```
|
```
|
||||||
106.从中序与后序遍历序列构造二叉树
|
106.从中序与后序遍历序列构造二叉树
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Definition for a binary tree node.
|
|
||||||
# class TreeNode:
|
|
||||||
# def __init__(self, val=0, left=None, right=None):
|
|
||||||
# self.val = val
|
|
||||||
# self.left = left
|
|
||||||
# self.right = right
|
|
||||||
//递归法
|
|
||||||
class Solution:
|
class Solution:
|
||||||
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
|
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
|
||||||
if not postorder: return None //特殊情况
|
# 第一步: 特殊情况讨论: 树为空. (递归终止条件)
|
||||||
root = TreeNode(postorder[-1]) //新建父节点
|
if not postorder:
|
||||||
p=inorder.index(postorder[-1]) //找到父节点在中序遍历的位置*因为没有重复的元素,才可以这样找
|
return None
|
||||||
root.left = self.buildTree(inorder[:p],postorder[:p]) //分割中序数组和后续数组
|
|
||||||
root.right = self.buildTree(inorder[p+1:],postorder[p:-1]) //注意右节点时分割中序数组和后续数组的开闭环
|
# 第二步: 后序遍历的最后一个就是当前的中间节点.
|
||||||
return root
|
root_val = postorder[-1]
|
||||||
|
root = TreeNode(root_val)
|
||||||
|
|
||||||
|
# 第三步: 找切割点.
|
||||||
|
separator_idx = inorder.index(root_val)
|
||||||
|
|
||||||
|
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
|
||||||
|
inorder_left = inorder[:separator_idx]
|
||||||
|
inorder_right = inorder[separator_idx + 1:]
|
||||||
|
|
||||||
|
# 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
|
||||||
|
# ⭐️ 重点1: 中序数组大小一定跟后序数组大小是相同的.
|
||||||
|
postorder_left = postorder[:len(inorder_left)]
|
||||||
|
postorder_right = postorder[len(inorder_left): len(postorder) - 1]
|
||||||
|
|
||||||
|
# 第六步: 递归
|
||||||
|
root.left = self.buildTree(inorder_left, postorder_left)
|
||||||
|
root.right = self.buildTree(inorder_right, postorder_right)
|
||||||
|
|
||||||
|
return root
|
||||||
```
|
```
|
||||||
Go:
|
Go:
|
||||||
> 106 从中序与后序遍历序列构造二叉树
|
> 106 从中序与后序遍历序列构造二叉树
|
||||||
|
@ -416,6 +416,8 @@ class Solution {
|
|||||||
Python:
|
Python:
|
||||||
|
|
||||||
0112.路径总和
|
0112.路径总和
|
||||||
|
|
||||||
|
**递归**
|
||||||
```python
|
```python
|
||||||
# Definition for a binary tree node.
|
# Definition for a binary tree node.
|
||||||
# class TreeNode:
|
# class TreeNode:
|
||||||
@ -424,28 +426,56 @@ Python:
|
|||||||
# self.left = left
|
# self.left = left
|
||||||
# self.right = right
|
# self.right = right
|
||||||
|
|
||||||
// 递归法
|
|
||||||
|
|
||||||
class Solution:
|
class Solution:
|
||||||
def hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
|
def hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
|
||||||
def isornot(root,targetSum)->bool:
|
def isornot(root, targetSum) -> bool:
|
||||||
if (not root.left) and (not root.right) and targetSum == 0:return True // 遇到叶子节点,并且计数为0
|
if (not root.left) and (not root.right) and targetSum == 0:
|
||||||
if (not root.left) and (not root.right):return False //遇到叶子节点,计数不为0
|
return True # 遇到叶子节点,并且计数为0
|
||||||
|
if (not root.left) and (not root.right):
|
||||||
|
return False # 遇到叶子节点,计数不为0
|
||||||
if root.left:
|
if root.left:
|
||||||
targetSum -= root.left.val //左节点
|
targetSum -= root.left.val # 左节点
|
||||||
if isornot(root.left,targetSum):return True //递归,处理左节点
|
if isornot(root.left, targetSum): return True # 递归,处理左节点
|
||||||
targetSum += root.left.val //回溯
|
targetSum += root.left.val # 回溯
|
||||||
if root.right:
|
if root.right:
|
||||||
targetSum -= root.right.val //右节点
|
targetSum -= root.right.val # 右节点
|
||||||
if isornot(root.right,targetSum):return True //递归,处理右节点
|
if isornot(root.right, targetSum): return True # 递归,处理右节点
|
||||||
targetSum += root.right.val //回溯
|
targetSum += root.right.val # 回溯
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if root == None:return False //别忘记处理空TreeNode
|
if root == None:
|
||||||
else:return isornot(root,targetSum-root.val)
|
return False # 别忘记处理空TreeNode
|
||||||
|
else:
|
||||||
|
return isornot(root, targetSum - root.val)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**迭代 - 层序遍历**
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
|
||||||
|
if not root:
|
||||||
|
return False
|
||||||
|
|
||||||
|
stack = [] # [(当前节点,路径数值), ...]
|
||||||
|
stack.append((root, root.val))
|
||||||
|
|
||||||
|
while stack:
|
||||||
|
cur_node, path_sum = stack.pop()
|
||||||
|
|
||||||
|
if not cur_node.left and not cur_node.right and path_sum == targetSum:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if cur_node.right:
|
||||||
|
stack.append((cur_node.right, path_sum + cur_node.right.val))
|
||||||
|
|
||||||
|
if cur_node.left:
|
||||||
|
stack.append((cur_node.left, path_sum + cur_node.left.val))
|
||||||
|
|
||||||
|
return False
|
||||||
|
```
|
||||||
0113.路径总和-ii
|
0113.路径总和-ii
|
||||||
|
|
||||||
|
**递归**
|
||||||
```python
|
```python
|
||||||
# Definition for a binary tree node.
|
# Definition for a binary tree node.
|
||||||
# class TreeNode:
|
# class TreeNode:
|
||||||
@ -453,35 +483,36 @@ class Solution:
|
|||||||
# self.val = val
|
# self.val = val
|
||||||
# self.left = left
|
# self.left = left
|
||||||
# self.right = right
|
# self.right = right
|
||||||
//递归法
|
|
||||||
class Solution:
|
class Solution:
|
||||||
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
|
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
|
||||||
path=[]
|
|
||||||
res=[]
|
|
||||||
def pathes(root,targetSum):
|
|
||||||
if (not root.left) and (not root.right) and targetSum == 0: // 遇到叶子节点,并且计数为0
|
|
||||||
res.append(path[:]) //找到一种路径,记录到res中,注意必须是path[:]而不是path
|
|
||||||
return
|
|
||||||
if (not root.left) and (not root.right):return // 遇到叶子节点直接返回
|
|
||||||
if root.left: //左
|
|
||||||
targetSum -= root.left.val
|
|
||||||
path.append(root.left.val) //递归前记录节点
|
|
||||||
pathes(root.left,targetSum) //递归
|
|
||||||
targetSum += root.left.val //回溯
|
|
||||||
path.pop() //回溯
|
|
||||||
if root.right: //右
|
|
||||||
targetSum -= root.right.val
|
|
||||||
path.append(root.right.val) //递归前记录节点
|
|
||||||
pathes(root.right,targetSum) //递归
|
|
||||||
targetSum += root.right.val //回溯
|
|
||||||
path.pop() //回溯
|
|
||||||
return
|
|
||||||
|
|
||||||
if root == None:return [] //处理空TreeNode
|
def traversal(cur_node, remain):
|
||||||
else:
|
if not cur_node.left and not cur_node.right and remain == 0:
|
||||||
path.append(root.val) //首先处理根节点
|
result.append(path[:])
|
||||||
pathes(root,targetSum-root.val)
|
return
|
||||||
return res
|
|
||||||
|
if not cur_node.left and not cur_node.right: return
|
||||||
|
|
||||||
|
if cur_node.left:
|
||||||
|
path.append(cur_node.left.val)
|
||||||
|
remain -= cur_node.left.val
|
||||||
|
traversal(cur_node.left, remain)
|
||||||
|
path.pop()
|
||||||
|
remain += cur_node.left.val
|
||||||
|
|
||||||
|
if cur_node.right:
|
||||||
|
path.append(cur_node.right.val)
|
||||||
|
remain -= cur_node.right.val
|
||||||
|
traversal(cur_node.right, remain)
|
||||||
|
path.pop()
|
||||||
|
remain += cur_node.right.val
|
||||||
|
|
||||||
|
result, path = [], []
|
||||||
|
if not root:
|
||||||
|
return []
|
||||||
|
path.append(root.val)
|
||||||
|
traversal(root, targetSum - root.val)
|
||||||
|
return result
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
|
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
|
||||||
|
|
||||||
如果链表中存在环,则返回 true 。 否则,返回 false 。
|
如果链表中存在环,则返回 true 。 否则,返回 false 。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
# 思路
|
# 思路
|
||||||
@ -74,6 +74,21 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
public class Solution {
|
||||||
|
public boolean hasCycle(ListNode head) {
|
||||||
|
ListNode fast = head;
|
||||||
|
ListNode slow = head;
|
||||||
|
// 空链表、单节点链表一定不会有环
|
||||||
|
while (fast != null && fast.next != null) {
|
||||||
|
fast = fast.next.next; // 快指针,一次移动两步
|
||||||
|
slow = slow.next; // 慢指针,一次移动一步
|
||||||
|
if (fast == slow) { // 快慢指针相遇,表明有环
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // 正常走到链表末尾,表明没有环
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||||
@ -63,6 +62,7 @@ public:
|
|||||||
## 方法二
|
## 方法二
|
||||||
|
|
||||||
把链表放进双向队列,然后通过双向队列一前一后弹出数据,来构造新的链表。这种方法比操作数组容易一些,不用双指针模拟一前一后了
|
把链表放进双向队列,然后通过双向队列一前一后弹出数据,来构造新的链表。这种方法比操作数组容易一些,不用双指针模拟一前一后了
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
class Solution {
|
class Solution {
|
||||||
public:
|
public:
|
||||||
@ -176,6 +176,51 @@ public:
|
|||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ReorderList {
|
||||||
|
public void reorderList(ListNode head) {
|
||||||
|
ListNode fast = head, slow = head;
|
||||||
|
//求出中点
|
||||||
|
while (fast.next != null && fast.next.next != null) {
|
||||||
|
slow = slow.next;
|
||||||
|
fast = fast.next.next;
|
||||||
|
}
|
||||||
|
//right就是右半部分 12345 就是45 1234 就是34
|
||||||
|
ListNode right = slow.next;
|
||||||
|
//断开左部分和右部分
|
||||||
|
slow.next = null;
|
||||||
|
//反转右部分 right就是反转后右部分的起点
|
||||||
|
right = reverseList(right);
|
||||||
|
//左部分的起点
|
||||||
|
ListNode left = head;
|
||||||
|
//进行左右部分来回连接
|
||||||
|
//这里左部分的节点个数一定大于等于右部分的节点个数 因此只判断right即可
|
||||||
|
while (right != null) {
|
||||||
|
ListNode curLeft = left.next;
|
||||||
|
left.next = right;
|
||||||
|
left = curLeft;
|
||||||
|
|
||||||
|
ListNode curRight = right.next;
|
||||||
|
right.next = left;
|
||||||
|
right = curRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode reverseList(ListNode head) {
|
||||||
|
ListNode headNode = new ListNode(0);
|
||||||
|
ListNode cur = head;
|
||||||
|
ListNode next = null;
|
||||||
|
while (cur != null) {
|
||||||
|
next = cur.next;
|
||||||
|
cur.next = headNode.next;
|
||||||
|
headNode.next = cur;
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
return headNode.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
@ -183,8 +228,10 @@ Go:
|
|||||||
JavaScript:
|
JavaScript:
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
|
|
||||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
||||||
|
@ -68,6 +68,25 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
class Solution {
|
||||||
|
public boolean isIsomorphic(String s, String t) {
|
||||||
|
Map<Character, Character> map1 = new HashMap<>();
|
||||||
|
Map<Character, Character> map2 = new HashMap<>();
|
||||||
|
for (int i = 0, j = 0; i < s.length(); i++, j++) {
|
||||||
|
if (!map1.containsKey(s.charAt(i))) {
|
||||||
|
map1.put(s.charAt(i), t.charAt(j)); // map1保存 s[i] 到 t[j]的映射
|
||||||
|
}
|
||||||
|
if (!map2.containsKey(t.charAt(j))) {
|
||||||
|
map2.put(t.charAt(j), s.charAt(i)); // map2保存 t[j] 到 s[i]的映射
|
||||||
|
}
|
||||||
|
// 无法映射,返回 false
|
||||||
|
if (map1.get(s.charAt(i)) != t.charAt(j) || map2.get(t.charAt(j)) != s.charAt(i)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
@ -275,7 +275,50 @@ var reverseList = function(head) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Ruby:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# 双指针
|
||||||
|
# Definition for singly-linked list.
|
||||||
|
# class ListNode
|
||||||
|
# attr_accessor :val, :next
|
||||||
|
# def initialize(val = 0, _next = nil)
|
||||||
|
# @val = val
|
||||||
|
# @next = _next
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
def reverse_list(head)
|
||||||
|
# return nil if head.nil? # 循环判断条件亦能起到相同作用因此不必单独判断
|
||||||
|
cur, per = head, nil
|
||||||
|
until cur.nil?
|
||||||
|
tem = cur.next
|
||||||
|
cur.next = per
|
||||||
|
per = cur
|
||||||
|
cur = tem
|
||||||
|
end
|
||||||
|
per
|
||||||
|
end
|
||||||
|
|
||||||
|
# 递归
|
||||||
|
# Definition for singly-linked list.
|
||||||
|
# class ListNode
|
||||||
|
# attr_accessor :val, :next
|
||||||
|
# def initialize(val = 0, _next = nil)
|
||||||
|
# @val = val
|
||||||
|
# @next = _next
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
def reverse_list(head)
|
||||||
|
reverse(nil, head)
|
||||||
|
end
|
||||||
|
|
||||||
|
def reverse(pre, cur)
|
||||||
|
return pre if cur.nil?
|
||||||
|
tem = cur.next
|
||||||
|
cur.next = pre
|
||||||
|
reverse(cur, tem) # 通过递归实现双指针法中的更新操作
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -384,7 +384,7 @@ func (this *MyQueue) Peek() int {
|
|||||||
func (this *MyQueue) Empty() bool {
|
func (this *MyQueue) Empty() bool {
|
||||||
return len(this.stack) == 0 && len(this.back) == 0
|
return len(this.stack) == 0 && len(this.back) == 0
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
javaScript:
|
javaScript:
|
||||||
|
|
||||||
@ -442,8 +442,6 @@ MyQueue.prototype.empty = function() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||||
|
@ -64,6 +64,21 @@ public:
|
|||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public void moveZeroes(int[] nums) {
|
||||||
|
int slow = 0;
|
||||||
|
for (int fast = 0; fast < nums.length; fast++) {
|
||||||
|
if (nums[fast] != 0) {
|
||||||
|
nums[slow++] = nums[fast];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 后面的元素全变成 0
|
||||||
|
for (int j = slow; j < nums.length; j++) {
|
||||||
|
nums[j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -205,25 +205,51 @@ class Solution {
|
|||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
```Python
|
|
||||||
**递归**
|
**递归**
|
||||||
# Definition for a binary tree node.
|
```python
|
||||||
# class TreeNode:
|
|
||||||
# def __init__(self, val=0, left=None, right=None):
|
|
||||||
# self.val = val
|
|
||||||
# self.left = left
|
|
||||||
# self.right = right
|
|
||||||
class Solution:
|
class Solution:
|
||||||
def sumOfLeftLeaves(self, root: TreeNode) -> int:
|
def sumOfLeftLeaves(self, root: TreeNode) -> int:
|
||||||
self.res=0
|
if not root:
|
||||||
def areleftleaves(root):
|
return 0
|
||||||
if not root:return
|
|
||||||
if root.left and (not root.left.left) and (not root.left.right):self.res+=root.left.val
|
left_left_leaves_sum = self.sumOfLeftLeaves(root.left) # 左
|
||||||
areleftleaves(root.left)
|
right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右
|
||||||
areleftleaves(root.right)
|
|
||||||
areleftleaves(root)
|
cur_left_leaf_val = 0
|
||||||
return self.res
|
if root.left and not root.left.left and not root.left.right:
|
||||||
|
cur_left_leaf_val = root.left.val # 中
|
||||||
|
|
||||||
|
return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**迭代**
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def sumOfLeftLeaves(self, root: TreeNode) -> int:
|
||||||
|
"""
|
||||||
|
Idea: Each time check current node's left node.
|
||||||
|
If current node don't have one, skip it.
|
||||||
|
"""
|
||||||
|
stack = []
|
||||||
|
if root:
|
||||||
|
stack.append(root)
|
||||||
|
res = 0
|
||||||
|
|
||||||
|
while stack:
|
||||||
|
# 每次都把当前节点的左节点加进去.
|
||||||
|
cur_node = stack.pop()
|
||||||
|
if cur_node.left and not cur_node.left.left and not cur_node.left.right:
|
||||||
|
res += cur_node.left.val
|
||||||
|
|
||||||
|
if cur_node.left:
|
||||||
|
stack.append(cur_node.left)
|
||||||
|
if cur_node.right:
|
||||||
|
stack.append(cur_node.right)
|
||||||
|
|
||||||
|
return res
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
> 递归法
|
> 递归法
|
||||||
|
@ -211,6 +211,29 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Java:
|
||||||
|
按左边排序,不管右边顺序。相交的时候取最小的右边。
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
public int eraseOverlapIntervals(int[][] intervals) {
|
||||||
|
|
||||||
|
Arrays.sort(intervals,(a,b)->{
|
||||||
|
return Integer.compare(a[0],b[0]);
|
||||||
|
});
|
||||||
|
int remove = 0;
|
||||||
|
int pre = intervals[0][1];
|
||||||
|
for(int i=1;i<intervals.length;i++){
|
||||||
|
if(pre>intervals[i][0]) {
|
||||||
|
remove++;
|
||||||
|
pre = Math.min(pre,intervals[i][1]);
|
||||||
|
}
|
||||||
|
else pre = intervals[i][1];
|
||||||
|
}
|
||||||
|
return remove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
|
@ -289,8 +289,79 @@ func repeatedSubstringPattern(s string) bool {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
JavaScript版本
|
||||||
|
|
||||||
|
> 前缀表统一减一
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* @param {string} s
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
var repeatedSubstringPattern = function (s) {
|
||||||
|
if (s.length === 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const getNext = (s) => {
|
||||||
|
let next = [];
|
||||||
|
let j = -1;
|
||||||
|
|
||||||
|
next.push(j);
|
||||||
|
|
||||||
|
for (let i = 1; i < s.length; ++i) {
|
||||||
|
while (j >= 0 && s[i] !== s[j + 1])
|
||||||
|
j = next[j];
|
||||||
|
if (s[i] === s[j + 1])
|
||||||
|
j++;
|
||||||
|
next.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = getNext(s);
|
||||||
|
|
||||||
|
if (next[next.length - 1] !== -1 && s.length % (s.length - (next[next.length - 1] + 1)) === 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 前缀表统一不减一
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* @param {string} s
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
var repeatedSubstringPattern = function (s) {
|
||||||
|
if (s.length === 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const getNext = (s) => {
|
||||||
|
let next = [];
|
||||||
|
let j = 0;
|
||||||
|
|
||||||
|
next.push(j);
|
||||||
|
|
||||||
|
for (let i = 1; i < s.length; ++i) {
|
||||||
|
while (j > 0 && s[i] !== s[j])
|
||||||
|
j = next[j - 1];
|
||||||
|
if (s[i] === s[j])
|
||||||
|
j++;
|
||||||
|
next.push(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = getNext(s);
|
||||||
|
|
||||||
|
if (next[next.length - 1] !== 0 && s.length % (s.length - next[next.length - 1]) === 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,27 +274,51 @@ class Solution {
|
|||||||
|
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
**递归 - 回溯**
|
||||||
```python
|
```python
|
||||||
//递归法
|
|
||||||
# Definition for a binary tree node.
|
|
||||||
# class TreeNode:
|
|
||||||
# def __init__(self, val=0, left=None, right=None):
|
|
||||||
# self.val = val
|
|
||||||
# self.left = left
|
|
||||||
# self.right = right
|
|
||||||
class Solution:
|
class Solution:
|
||||||
def findBottomLeftValue(self, root: TreeNode) -> int:
|
def findBottomLeftValue(self, root: TreeNode) -> int:
|
||||||
depth=0
|
max_depth = -float("INF")
|
||||||
self.res=[]
|
leftmost_val = 0
|
||||||
def level(root,depth):
|
|
||||||
if not root:return
|
def __traverse(root, cur_depth):
|
||||||
if depth==len(self.res):
|
nonlocal max_depth, leftmost_val
|
||||||
self.res.append([])
|
if not root.left and not root.right:
|
||||||
self.res[depth].append(root.val)
|
if cur_depth > max_depth:
|
||||||
level(root.left,depth+1)
|
max_depth = cur_depth
|
||||||
level(root.right,depth+1)
|
leftmost_val = root.val
|
||||||
level(root,depth)
|
if root.left:
|
||||||
return self.res[-1][0]
|
cur_depth += 1
|
||||||
|
__traverse(root.left, cur_depth)
|
||||||
|
cur_depth -= 1
|
||||||
|
if root.right:
|
||||||
|
cur_depth += 1
|
||||||
|
__traverse(root.right, cur_depth)
|
||||||
|
cur_depth -= 1
|
||||||
|
|
||||||
|
__traverse(root, 0)
|
||||||
|
return leftmost_val
|
||||||
|
```
|
||||||
|
**迭代 - 层序遍历**
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def findBottomLeftValue(self, root: TreeNode) -> int:
|
||||||
|
queue = deque()
|
||||||
|
if root:
|
||||||
|
queue.append(root)
|
||||||
|
result = 0
|
||||||
|
while queue:
|
||||||
|
q_len = len(queue)
|
||||||
|
for i in range(q_len):
|
||||||
|
if i == 0:
|
||||||
|
result = queue[i].val
|
||||||
|
cur = queue.popleft()
|
||||||
|
if cur.left:
|
||||||
|
queue.append(cur.left)
|
||||||
|
if cur.right:
|
||||||
|
queue.append(cur.right)
|
||||||
|
return result
|
||||||
```
|
```
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -71,21 +71,84 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
// 时间复杂度:O(n)
|
||||||
|
// 空间复杂度:如果采用 toCharArray,则是 O(n);如果使用 charAt,则是 O(1)
|
||||||
|
class Solution {
|
||||||
|
public boolean judgeCircle(String moves) {
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
for (char c : moves.toCharArray()) {
|
||||||
|
if (c == 'U') y++;
|
||||||
|
if (c == 'D') y--;
|
||||||
|
if (c == 'L') x++;
|
||||||
|
if (c == 'R') x--;
|
||||||
|
}
|
||||||
|
return x == 0 && y == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
# 时间复杂度:O(n)
|
||||||
|
# 空间复杂度:O(1)
|
||||||
|
class Solution:
|
||||||
|
def judgeCircle(self, moves: str) -> bool:
|
||||||
|
x = 0 # 记录当前位置
|
||||||
|
y = 0
|
||||||
|
for i in range(len(moves)):
|
||||||
|
if (moves[i] == 'U'):
|
||||||
|
y += 1
|
||||||
|
if (moves[i] == 'D'):
|
||||||
|
y -= 1
|
||||||
|
if (moves[i] == 'L'):
|
||||||
|
x += 1
|
||||||
|
if (moves[i] == 'R'):
|
||||||
|
x -= 1
|
||||||
|
return x == 0 and y == 0
|
||||||
```
|
```
|
||||||
|
|
||||||
## Go
|
## Go
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
func judgeCircle(moves string) bool {
|
||||||
|
x := 0
|
||||||
|
y := 0
|
||||||
|
for i := 0; i < len(moves); i++ {
|
||||||
|
if moves[i] == 'U' {
|
||||||
|
y++
|
||||||
|
}
|
||||||
|
if moves[i] == 'D' {
|
||||||
|
y--
|
||||||
|
}
|
||||||
|
if moves[i] == 'L' {
|
||||||
|
x++
|
||||||
|
}
|
||||||
|
if moves[i] == 'R' {
|
||||||
|
x--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x == 0 && y == 0;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## JavaScript
|
## JavaScript
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// 时间复杂度:O(n)
|
||||||
|
// 空间复杂度:O(1)
|
||||||
|
var judgeCircle = function(moves) {
|
||||||
|
var x = 0; // 记录当前位置
|
||||||
|
var y = 0;
|
||||||
|
for (var i = 0; i < moves.length; i++) {
|
||||||
|
if (moves[i] == 'U') y++;
|
||||||
|
if (moves[i] == 'D') y--;
|
||||||
|
if (moves[i] == 'L') x++;
|
||||||
|
if (moves[i] == 'R') x--;
|
||||||
|
}
|
||||||
|
return x == 0 && y == 0;
|
||||||
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -235,8 +235,6 @@ class Solution:
|
|||||||
return -1
|
return -1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Go:**
|
**Go:**
|
||||||
|
|
||||||
(版本一)左闭右闭区间
|
(版本一)左闭右闭区间
|
||||||
@ -279,7 +277,7 @@ func search(nums []int, target int) int {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**javaScript:**
|
**JavaScript:**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
||||||
@ -316,7 +314,43 @@ var search = function(nums, target) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Ruby:**
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
# (版本一)左闭右闭区间
|
||||||
|
|
||||||
|
def search(nums, target)
|
||||||
|
left, right = 0, nums.length - 1
|
||||||
|
while left <= right # 由于定义target在一个在左闭右闭的区间里,因此极限情况下存在left==right
|
||||||
|
middle = (left + right) / 2
|
||||||
|
if nums[middle] > target
|
||||||
|
right = middle - 1
|
||||||
|
elsif nums[middle] < target
|
||||||
|
left = middle + 1
|
||||||
|
else
|
||||||
|
return middle # return兼具返回与跳出循环的作用
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-1
|
||||||
|
end
|
||||||
|
|
||||||
|
# (版本二)左闭右开区间
|
||||||
|
|
||||||
|
def search(nums, target)
|
||||||
|
left, right = 0, nums.length
|
||||||
|
while left < right # 由于定义target在一个在左闭右开的区间里,因此极限情况下right=left+1
|
||||||
|
middle = (left + right) / 2
|
||||||
|
if nums[middle] > target
|
||||||
|
right = middle
|
||||||
|
elsif nums[middle] < target
|
||||||
|
left = middle + 1
|
||||||
|
else
|
||||||
|
return middle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-1
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,6 +252,33 @@ func findLength(A []int, B []int) int {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
JavaScript:
|
||||||
|
|
||||||
|
> 动态规划
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const findLength = (A, B) => {
|
||||||
|
// A、B数组的长度
|
||||||
|
const [m, n] = [A.length, B.length];
|
||||||
|
// dp数组初始化,都初始化为0
|
||||||
|
const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
|
||||||
|
// 初始化最大长度为0
|
||||||
|
let res = 0;
|
||||||
|
for (let i = 1; i <= m; i++) {
|
||||||
|
for (let j = 1; j <= n; j++) {
|
||||||
|
// 遇到A[i - 1] === B[j - 1],则更新dp数组
|
||||||
|
if (A[i - 1] === B[j - 1]) {
|
||||||
|
dp[i][j] = dp[i - 1][j - 1] + 1;
|
||||||
|
}
|
||||||
|
// 更新res
|
||||||
|
res = dp[i][j] > res ? dp[i][j] : res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 遍历完成,返回res
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -67,6 +67,24 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
class Solution {
|
||||||
|
public int pivotIndex(int[] nums) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
sum += nums[i]; // 总和
|
||||||
|
}
|
||||||
|
int leftSum = 0;
|
||||||
|
int rightSum = 0;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
leftSum += nums[i];
|
||||||
|
rightSum = sum - leftSum + nums[i]; // leftSum 里面已经有 nums[i],多减了一次,所以加上
|
||||||
|
if (leftSum == rightSum) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // 不存在
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
@ -90,4 +108,3 @@ public:
|
|||||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。
|
给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。
|
||||||
|
|
||||||
注意:如果对空文本输入退格字符,文本继续为空。
|
注意:如果对空文本输入退格字符,文本继续为空。
|
||||||
|
|
||||||
示例 1:
|
示例 1:
|
||||||
* 输入:S = "ab#c", T = "ad#c"
|
* 输入:S = "ab#c", T = "ad#c"
|
||||||
* 输出:true
|
* 输出:true
|
||||||
@ -160,6 +160,32 @@ public:
|
|||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 普通方法(使用栈的思路)
|
||||||
|
class Solution {
|
||||||
|
public boolean backspaceCompare(String s, String t) {
|
||||||
|
StringBuilder ssb = new StringBuilder(); // 模拟栈
|
||||||
|
StringBuilder tsb = new StringBuilder(); // 模拟栈
|
||||||
|
// 分别处理两个 String
|
||||||
|
for (char c : s.toCharArray()) {
|
||||||
|
if (c != '#') {
|
||||||
|
ssb.append(c); // 模拟入栈
|
||||||
|
} else if (ssb.length() > 0){ // 栈非空才能弹栈
|
||||||
|
ssb.deleteCharAt(ssb.length() - 1); // 模拟弹栈
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (char c : t.toCharArray()) {
|
||||||
|
if (c != '#') {
|
||||||
|
tsb.append(c); // 模拟入栈
|
||||||
|
} else if (tsb.length() > 0){ // 栈非空才能弹栈
|
||||||
|
tsb.deleteCharAt(tsb.length() - 1); // 模拟弹栈
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ssb.toString().equals(tsb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
@ -120,6 +120,31 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
// 方法一
|
||||||
|
class Solution {
|
||||||
|
public int[] sortArrayByParityII(int[] nums) {
|
||||||
|
// 分别存放 nums 中的奇数、偶数
|
||||||
|
int len = nums.length;
|
||||||
|
int evenIndex = 0;
|
||||||
|
int oddIndex = 0;
|
||||||
|
int[] even = new int[len / 2];
|
||||||
|
int[] odd = new int[len / 2];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (nums[i] % 2 == 0) {
|
||||||
|
even[evenIndex++] = nums[i];
|
||||||
|
} else {
|
||||||
|
odd[oddIndex++] = nums[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 把奇偶数组重新存回 nums
|
||||||
|
int index = 0;
|
||||||
|
for (int i = 0; i < even.length; i++) {
|
||||||
|
nums[index++] = even[i];
|
||||||
|
nums[index++] = odd[i];
|
||||||
|
}
|
||||||
|
return nums;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
@ -143,4 +168,3 @@ public:
|
|||||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ https://leetcode-cn.com/problems/valid-mountain-array/
|
|||||||
|
|
||||||
C++代码如下:
|
C++代码如下:
|
||||||
|
|
||||||
```
|
```c++
|
||||||
class Solution {
|
class Solution {
|
||||||
public:
|
public:
|
||||||
bool validMountainArray(vector<int>& A) {
|
bool validMountainArray(vector<int>& A) {
|
||||||
@ -38,6 +38,33 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
Java 版本如下:
|
||||||
|
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
public boolean validMountainArray(int[] arr) {
|
||||||
|
if (arr.length < 3) { // 此时,一定不是有效的山脉数组
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 双指针
|
||||||
|
int left = 0;
|
||||||
|
int right = arr.length - 1;
|
||||||
|
// 注意防止指针越界
|
||||||
|
while (left + 1 < arr.length && arr[left] < arr[left + 1]) {
|
||||||
|
left++;
|
||||||
|
}
|
||||||
|
// 注意防止指针越界
|
||||||
|
while (right > 0 && arr[right] < arr[right - 1]) {
|
||||||
|
right--;
|
||||||
|
}
|
||||||
|
// 如果left或者right都在起始位置,说明不是山峰
|
||||||
|
if (left == right && left != 0 && right != arr.length - 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
如果想系统学一学双指针的话, 可以看一下这篇[双指针法:总结篇!](https://mp.weixin.qq.com/s/_p7grwjISfMh0U65uOyCjA)
|
如果想系统学一学双指针的话, 可以看一下这篇[双指针法:总结篇!](https://mp.weixin.qq.com/s/_p7grwjISfMh0U65uOyCjA)
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,6 +77,28 @@ public:
|
|||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
public boolean uniqueOccurrences(int[] arr) {
|
||||||
|
int[] count = new int[2002];
|
||||||
|
for (int i = 0; i < arr.length; i++) {
|
||||||
|
count[arr[i] + 1000]++; // 防止负数作为下标
|
||||||
|
}
|
||||||
|
boolean[] flag = new boolean[1002]; // 标记相同频率是否重复出现
|
||||||
|
for (int i = 0; i <= 2000; i++) {
|
||||||
|
if (count[i] > 0) {
|
||||||
|
if (flag[count[i]] == false) {
|
||||||
|
flag[count[i]] = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
@ -89,4 +111,3 @@ JavaScript:
|
|||||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。
|
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。
|
||||||
|
|
||||||
以数组形式返回答案。
|
以数组形式返回答案。
|
||||||
|
|
||||||
|
|
||||||
示例 1:
|
示例 1:
|
||||||
输入:nums = [8,1,2,2,3]
|
输入:nums = [8,1,2,2,3]
|
||||||
@ -35,7 +35,7 @@
|
|||||||
示例 3:
|
示例 3:
|
||||||
输入:nums = [7,7,7,7]
|
输入:nums = [7,7,7,7]
|
||||||
输出:[0,0,0,0]
|
输出:[0,0,0,0]
|
||||||
|
|
||||||
提示:
|
提示:
|
||||||
* 2 <= nums.length <= 500
|
* 2 <= nums.length <= 500
|
||||||
* 0 <= nums[i] <= 100
|
* 0 <= nums[i] <= 100
|
||||||
@ -120,8 +120,51 @@ public:
|
|||||||
## Java
|
## Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
/**
|
||||||
|
* 解法一:暴力
|
||||||
|
* 时间复杂度:O(n^2)
|
||||||
|
* 空间复杂度:O(n)
|
||||||
|
*/
|
||||||
|
class Solution {
|
||||||
|
public int[] smallerNumbersThanCurrent(int[] nums) {
|
||||||
|
int[] res = new int[nums.length];
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
for (int j = 0; j < nums.length; j++) {
|
||||||
|
if (nums[j] < nums[i] && j != i) { // 注意 j 不能和 i 重合
|
||||||
|
res[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 优化:排序 + 哈希表
|
||||||
|
* 时间复杂度:O(nlogn)
|
||||||
|
* 空间复杂度:O(n)
|
||||||
|
*/
|
||||||
|
class Solution {
|
||||||
|
public int[] smallerNumbersThanCurrent(int[] nums) {
|
||||||
|
int[] res = Arrays.copyOf(nums, nums.length);
|
||||||
|
Arrays.sort(res); // 是对 res 排序,nums 中顺序还要保持
|
||||||
|
int[] hash = new int[101]; // 使用哈希表,记录比当前元素小的元素个数
|
||||||
|
for (int i = res.length - 1; i >= 0; i--) { // 注意:从后向前
|
||||||
|
hash[res[i]] = i; // 排序后,当前下标即表示比当前元素小的元素个数
|
||||||
|
}
|
||||||
|
// 此时 hash中保存的每一个元素数值 便是 小于这个数值的个数
|
||||||
|
for (int i = 0; i < res.length; i++) {
|
||||||
|
res[i] = hash[nums[i]];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Python
|
## Python
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@ -143,4 +186,3 @@ public:
|
|||||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ Go:
|
|||||||
|
|
||||||
前序遍历:
|
前序遍历:
|
||||||
```go
|
```go
|
||||||
func PreorderTraversal(root *TreeNode) (res []int) {
|
func preorderTraversal(root *TreeNode) (res []int) {
|
||||||
var traversal func(node *TreeNode)
|
var traversal func(node *TreeNode)
|
||||||
traversal = func(node *TreeNode) {
|
traversal = func(node *TreeNode) {
|
||||||
if node == nil {
|
if node == nil {
|
||||||
@ -240,7 +240,7 @@ func PreorderTraversal(root *TreeNode) (res []int) {
|
|||||||
中序遍历:
|
中序遍历:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func InorderTraversal(root *TreeNode) (res []int) {
|
func inorderTraversal(root *TreeNode) (res []int) {
|
||||||
var traversal func(node *TreeNode)
|
var traversal func(node *TreeNode)
|
||||||
traversal = func(node *TreeNode) {
|
traversal = func(node *TreeNode) {
|
||||||
if node == nil {
|
if node == nil {
|
||||||
@ -257,7 +257,7 @@ func InorderTraversal(root *TreeNode) (res []int) {
|
|||||||
后序遍历:
|
后序遍历:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func PostorderTraversal(root *TreeNode) (res []int) {
|
func postorderTraversal(root *TreeNode) (res []int) {
|
||||||
var traversal func(node *TreeNode)
|
var traversal func(node *TreeNode)
|
||||||
traversal = func(node *TreeNode) {
|
traversal = func(node *TreeNode) {
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
@ -165,6 +165,22 @@ func reverse(b []byte, left, right int){
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
JavaScript:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var reverseLeftWords = function (s, n) {
|
||||||
|
const reverse = (str, left, right) => {
|
||||||
|
let strArr = str.split("");
|
||||||
|
for (; left < right; left++, right--) {
|
||||||
|
[strArr[left], strArr[right]] = [strArr[right], strArr[left]];
|
||||||
|
}
|
||||||
|
return strArr.join("");
|
||||||
|
}
|
||||||
|
s = reverse(s, 0, n - 1);
|
||||||
|
s = reverse(s, n, s.length - 1);
|
||||||
|
return reverse(s, 0, s.length - 1);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user