mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 08:50:15 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -289,6 +289,30 @@ func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? {
|
||||
return dummyHead.next
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
function removeNthFromEnd($head, $n) {
|
||||
// 设置虚拟头节点
|
||||
$dummyHead = new ListNode();
|
||||
$dummyHead->next = $head;
|
||||
|
||||
$slow = $fast = $dummyHead;
|
||||
while($n-- && $fast != null){
|
||||
$fast = $fast->next;
|
||||
}
|
||||
// fast 再走一步,让 slow 指向删除节点的上一个节点
|
||||
$fast = $fast->next;
|
||||
while ($fast != NULL) {
|
||||
$fast = $fast->next;
|
||||
$slow = $slow->next;
|
||||
}
|
||||
$slow->next = $slow->next->next;
|
||||
return $dummyHead->next;
|
||||
}
|
||||
```
|
||||
|
||||
Scala:
|
||||
```scala
|
||||
object Solution {
|
||||
|
@ -744,6 +744,91 @@ var trap = function(height) {
|
||||
};
|
||||
```
|
||||
|
||||
### TypeScript
|
||||
|
||||
双指针法:
|
||||
|
||||
```typescript
|
||||
function trap(height: number[]): number {
|
||||
const length: number = height.length;
|
||||
let resVal: number = 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
let leftMaxHeight: number = height[i],
|
||||
rightMaxHeight: number = height[i];
|
||||
let leftIndex: number = i - 1,
|
||||
rightIndex: number = i + 1;
|
||||
while (leftIndex >= 0) {
|
||||
if (height[leftIndex] > leftMaxHeight)
|
||||
leftMaxHeight = height[leftIndex];
|
||||
leftIndex--;
|
||||
}
|
||||
while (rightIndex < length) {
|
||||
if (height[rightIndex] > rightMaxHeight)
|
||||
rightMaxHeight = height[rightIndex];
|
||||
rightIndex++;
|
||||
}
|
||||
resVal += Math.min(leftMaxHeight, rightMaxHeight) - height[i];
|
||||
}
|
||||
return resVal;
|
||||
};
|
||||
```
|
||||
|
||||
动态规划:
|
||||
|
||||
```typescript
|
||||
function trap(height: number[]): number {
|
||||
const length: number = height.length;
|
||||
const leftMaxHeightDp: number[] = [],
|
||||
rightMaxHeightDp: number[] = [];
|
||||
leftMaxHeightDp[0] = height[0];
|
||||
rightMaxHeightDp[length - 1] = height[length - 1];
|
||||
for (let i = 1; i < length; i++) {
|
||||
leftMaxHeightDp[i] = Math.max(height[i], leftMaxHeightDp[i - 1]);
|
||||
}
|
||||
for (let i = length - 2; i >= 0; i--) {
|
||||
rightMaxHeightDp[i] = Math.max(height[i], rightMaxHeightDp[i + 1]);
|
||||
}
|
||||
let resVal: number = 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
resVal += Math.min(leftMaxHeightDp[i], rightMaxHeightDp[i]) - height[i];
|
||||
}
|
||||
return resVal;
|
||||
};
|
||||
```
|
||||
|
||||
单调栈:
|
||||
|
||||
```typescript
|
||||
function trap(height: number[]): number {
|
||||
const length: number = height.length;
|
||||
const stack: number[] = [];
|
||||
stack.push(0);
|
||||
let resVal: number = 0;
|
||||
for (let i = 1; i < length; i++) {
|
||||
let top = stack[stack.length - 1];
|
||||
if (height[top] > height[i]) {
|
||||
stack.push(i);
|
||||
} else if (height[top] === height[i]) {
|
||||
stack.pop();
|
||||
stack.push(i);
|
||||
} else {
|
||||
while (stack.length > 0 && height[top] < height[i]) {
|
||||
let mid = stack.pop();
|
||||
if (stack.length > 0) {
|
||||
let left = stack[stack.length - 1];
|
||||
let h = Math.min(height[left], height[i]) - height[mid];
|
||||
let w = i - left - 1;
|
||||
resVal += h * w;
|
||||
top = stack[stack.length - 1];
|
||||
}
|
||||
}
|
||||
stack.push(i);
|
||||
}
|
||||
}
|
||||
return resVal;
|
||||
};
|
||||
```
|
||||
|
||||
### C:
|
||||
|
||||
一种更简便的双指针方法:
|
||||
|
@ -341,7 +341,7 @@ function permute(nums: number[]): number[][] {
|
||||
return resArr;
|
||||
function backTracking(nums: number[], route: number[]): void {
|
||||
if (route.length === nums.length) {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
return;
|
||||
}
|
||||
let tempVal: number;
|
||||
|
@ -268,7 +268,7 @@ var permuteUnique = function (nums) {
|
||||
|
||||
function backtracing( used) {
|
||||
if (path.length === nums.length) {
|
||||
result.push(path.slice())
|
||||
result.push([...path])
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
@ -303,7 +303,7 @@ function permuteUnique(nums: number[]): number[][] {
|
||||
return resArr;
|
||||
function backTracking(nums: number[], route: number[]): void {
|
||||
if (route.length === nums.length) {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
return;
|
||||
}
|
||||
for (let i = 0, length = nums.length; i < length; i++) {
|
||||
|
@ -44,7 +44,7 @@ n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并
|
||||
# 思路
|
||||
|
||||
|
||||
想看:[51.N皇后](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg) ,基本没有区别
|
||||
详看:[51.N皇后](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg) ,基本没有区别
|
||||
|
||||
# C++代码
|
||||
|
||||
|
@ -260,7 +260,7 @@ var subsets = function(nums) {
|
||||
let result = []
|
||||
let path = []
|
||||
function backtracking(startIndex) {
|
||||
result.push(path.slice())
|
||||
result.push([...path])
|
||||
for(let i = startIndex; i < nums.length; i++) {
|
||||
path.push(nums[i])
|
||||
backtracking(i + 1)
|
||||
@ -280,7 +280,7 @@ function subsets(nums: number[]): number[][] {
|
||||
backTracking(nums, 0, []);
|
||||
return resArr;
|
||||
function backTracking(nums: number[], startIndex: number, route: number[]): void {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
let length = nums.length;
|
||||
if (startIndex === length) return;
|
||||
for (let i = startIndex; i < length; i++) {
|
||||
|
@ -486,5 +486,95 @@ var largestRectangleArea = function(heights) {
|
||||
return maxArea;
|
||||
};
|
||||
```
|
||||
TypeScript:
|
||||
|
||||
> 双指针法(会超时):
|
||||
|
||||
```typescript
|
||||
function largestRectangleArea(heights: number[]): number {
|
||||
let resMax: number = 0;
|
||||
for (let i = 0, length = heights.length; i < length; i++) {
|
||||
// 左开右开
|
||||
let left: number = i - 1,
|
||||
right: number = i + 1;
|
||||
while (left >= 0 && heights[left] >= heights[i]) {
|
||||
left--;
|
||||
}
|
||||
while (right < length && heights[right] >= heights[i]) {
|
||||
right++;
|
||||
}
|
||||
resMax = Math.max(resMax, heights[i] * (right - left - 1));
|
||||
}
|
||||
return resMax;
|
||||
};
|
||||
```
|
||||
|
||||
> 动态规划预处理:
|
||||
|
||||
```typescript
|
||||
function largestRectangleArea(heights: number[]): number {
|
||||
const length: number = heights.length;
|
||||
const leftHeightDp: number[] = [],
|
||||
rightHeightDp: number[] = [];
|
||||
leftHeightDp[0] = -1;
|
||||
rightHeightDp[length - 1] = length;
|
||||
for (let i = 1; i < length; i++) {
|
||||
let j = i - 1;
|
||||
while (j >= 0 && heights[i] <= heights[j]) {
|
||||
j = leftHeightDp[j];
|
||||
}
|
||||
leftHeightDp[i] = j;
|
||||
}
|
||||
for (let i = length - 2; i >= 0; i--) {
|
||||
let j = i + 1;
|
||||
while (j < length && heights[i] <= heights[j]) {
|
||||
j = rightHeightDp[j];
|
||||
}
|
||||
rightHeightDp[i] = j;
|
||||
}
|
||||
let resMax: number = 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
let area = heights[i] * (rightHeightDp[i] - leftHeightDp[i] - 1);
|
||||
resMax = Math.max(resMax, area);
|
||||
}
|
||||
return resMax;
|
||||
};
|
||||
```
|
||||
|
||||
> 单调栈:
|
||||
|
||||
```typescript
|
||||
function largestRectangleArea(heights: number[]): number {
|
||||
heights.push(0);
|
||||
const length: number = heights.length;
|
||||
// 栈底->栈顶:严格单调递增
|
||||
const stack: number[] = [];
|
||||
stack.push(0);
|
||||
let resMax: number = 0;
|
||||
for (let i = 1; i < length; i++) {
|
||||
let top = stack[stack.length - 1];
|
||||
if (heights[top] < heights[i]) {
|
||||
stack.push(i);
|
||||
} else if (heights[top] === heights[i]) {
|
||||
stack.pop();
|
||||
stack.push(i);
|
||||
} else {
|
||||
while (stack.length > 0 && heights[top] > heights[i]) {
|
||||
let mid = stack.pop();
|
||||
let left = stack.length > 0 ? stack[stack.length - 1] : -1;
|
||||
let w = i - left - 1;
|
||||
let h = heights[mid];
|
||||
resMax = Math.max(resMax, w * h);
|
||||
top = stack[stack.length - 1];
|
||||
}
|
||||
stack.push(i);
|
||||
}
|
||||
}
|
||||
return resMax;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -299,7 +299,7 @@ var subsetsWithDup = function(nums) {
|
||||
return a - b
|
||||
})
|
||||
function backtracing(startIndex, sortNums) {
|
||||
result.push(path.slice(0))
|
||||
result.push([...path])
|
||||
if(startIndex > nums.length - 1) {
|
||||
return
|
||||
}
|
||||
@ -327,7 +327,7 @@ function subsetsWithDup(nums: number[]): number[][] {
|
||||
backTraking(nums, 0, []);
|
||||
return resArr;
|
||||
function backTraking(nums: number[], startIndex: number, route: number[]): void {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
let length: number = nums.length;
|
||||
if (startIndex === length) return;
|
||||
for (let i = startIndex; i < length; i++) {
|
||||
|
@ -444,7 +444,7 @@ var restoreIpAddresses = function(s) {
|
||||
return;
|
||||
}
|
||||
for(let j = i; j < s.length; j++) {
|
||||
const str = s.substr(i, j - i + 1);
|
||||
const str = s.slice(i, j + 1);
|
||||
if(str.length > 3 || +str > 255) break;
|
||||
if(str.length > 1 && str[0] === "0") break;
|
||||
path.push(str);
|
||||
|
@ -495,7 +495,7 @@ class solution:
|
||||
|
||||
|
||||
## go
|
||||
|
||||
### 104.二叉树的最大深度
|
||||
```go
|
||||
/**
|
||||
* definition for a binary tree node.
|
||||
@ -548,6 +548,8 @@ func maxdepth(root *treenode) int {
|
||||
|
||||
## javascript
|
||||
|
||||
### 104.二叉树的最大深度
|
||||
|
||||
```javascript
|
||||
var maxdepth = function(root) {
|
||||
if (root === null) return 0;
|
||||
@ -595,6 +597,8 @@ var maxDepth = function(root) {
|
||||
};
|
||||
```
|
||||
|
||||
### 559.n叉树的最大深度
|
||||
|
||||
N叉树的最大深度 递归写法
|
||||
```js
|
||||
var maxDepth = function(root) {
|
||||
@ -627,9 +631,9 @@ var maxDepth = function(root) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript:
|
||||
## TypeScript
|
||||
|
||||
> 二叉树的最大深度:
|
||||
### 104.二叉树的最大深度
|
||||
|
||||
```typescript
|
||||
// 后续遍历(自下而上)
|
||||
@ -672,7 +676,7 @@ function maxDepth(root: TreeNode | null): number {
|
||||
};
|
||||
```
|
||||
|
||||
> N叉树的最大深度
|
||||
### 559.n叉树的最大深度
|
||||
|
||||
```typescript
|
||||
// 后续遍历(自下而上)
|
||||
@ -702,6 +706,8 @@ function maxDepth(root: TreeNode | null): number {
|
||||
|
||||
## C
|
||||
|
||||
### 104.二叉树的最大深度
|
||||
|
||||
二叉树最大深度递归
|
||||
```c
|
||||
int maxDepth(struct TreeNode* root){
|
||||
@ -758,7 +764,8 @@ int maxDepth(struct TreeNode* root){
|
||||
|
||||
## Swift
|
||||
|
||||
>二叉树最大深度
|
||||
### 104.二叉树的最大深度
|
||||
|
||||
```swift
|
||||
// 递归 - 后序
|
||||
func maxDepth1(_ root: TreeNode?) -> Int {
|
||||
@ -797,7 +804,8 @@ func maxDepth(_ root: TreeNode?) -> Int {
|
||||
}
|
||||
```
|
||||
|
||||
>N叉树最大深度
|
||||
### 559.n叉树的最大深度
|
||||
|
||||
```swift
|
||||
// 递归
|
||||
func maxDepth(_ root: Node?) -> Int {
|
||||
@ -833,5 +841,84 @@ func maxDepth1(_ root: Node?) -> Int {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
|
||||
### 104.二叉树的最大深度
|
||||
递归法:
|
||||
```scala
|
||||
object Solution {
|
||||
def maxDepth(root: TreeNode): Int = {
|
||||
def process(curNode: TreeNode): Int = {
|
||||
if (curNode == null) return 0
|
||||
// 递归左节点和右节点,返回最大的,最后+1
|
||||
math.max(process(curNode.left), process(curNode.right)) + 1
|
||||
}
|
||||
// 调用递归方法,return关键字可以省略
|
||||
process(root)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
迭代法:
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def maxDepth(root: TreeNode): Int = {
|
||||
var depth = 0
|
||||
if (root == null) return depth
|
||||
val queue = mutable.Queue[TreeNode]()
|
||||
queue.enqueue(root)
|
||||
while (!queue.isEmpty) {
|
||||
val len = queue.size
|
||||
for (i <- 0 until len) {
|
||||
val curNode = queue.dequeue()
|
||||
if (curNode.left != null) queue.enqueue(curNode.left)
|
||||
if (curNode.right != null) queue.enqueue(curNode.right)
|
||||
}
|
||||
depth += 1 // 只要有层次就+=1
|
||||
}
|
||||
depth
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 559.n叉树的最大深度
|
||||
|
||||
递归法:
|
||||
```scala
|
||||
object Solution {
|
||||
def maxDepth(root: Node): Int = {
|
||||
if (root == null) return 0
|
||||
var depth = 0
|
||||
for (node <- root.children) {
|
||||
depth = math.max(depth, maxDepth(node))
|
||||
}
|
||||
depth + 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
迭代法: (层序遍历)
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def maxDepth(root: Node): Int = {
|
||||
if (root == null) return 0
|
||||
var depth = 0
|
||||
val queue = mutable.Queue[Node]()
|
||||
queue.enqueue(root)
|
||||
while (!queue.isEmpty) {
|
||||
val len = queue.size
|
||||
depth += 1
|
||||
for (i <- 0 until len) {
|
||||
val curNode = queue.dequeue()
|
||||
for (node <- curNode.children) queue.enqueue(node)
|
||||
}
|
||||
}
|
||||
depth
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -1091,7 +1091,53 @@ class Solution_0106 {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
|
||||
106 从中序与后序遍历序列构造二叉树
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def buildTree(inorder: Array[Int], postorder: Array[Int]): TreeNode = {
|
||||
// 1、如果长度为0,则直接返回null
|
||||
var len = inorder.size
|
||||
if (len == 0) return null
|
||||
// 2、后序数组的最后一个元素是当前根元素
|
||||
var rootValue = postorder(len - 1)
|
||||
var root: TreeNode = new TreeNode(rootValue, null, null)
|
||||
if (len == 1) return root // 如果数组只有一个节点,就直接返回
|
||||
// 3、在中序数组中找到切割点的索引
|
||||
var delimiterIndex: Int = inorder.indexOf(rootValue)
|
||||
// 4、切分数组往下迭代
|
||||
root.left = buildTree(inorder.slice(0, delimiterIndex), postorder.slice(0, delimiterIndex))
|
||||
root.right = buildTree(inorder.slice(delimiterIndex + 1, len), postorder.slice(delimiterIndex, len - 1))
|
||||
root // 返回root,return关键字可以省略
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
105 从前序与中序遍历序列构造二叉树
|
||||
|
||||
```scala
|
||||
object Solution {
|
||||
def buildTree(preorder: Array[Int], inorder: Array[Int]): TreeNode = {
|
||||
// 1、如果长度为0,直接返回空
|
||||
var len = inorder.size
|
||||
if (len == 0) return null
|
||||
// 2、前序数组的第一个元素是当前子树根节点
|
||||
var rootValue = preorder(0)
|
||||
var root = new TreeNode(rootValue, null, null)
|
||||
if (len == 1) return root // 如果数组元素只有一个,那么返回根节点
|
||||
// 3、在中序数组中,找到切割点
|
||||
var delimiterIndex = inorder.indexOf(rootValue)
|
||||
|
||||
// 4、切分数组往下迭代
|
||||
root.left = buildTree(preorder.slice(1, delimiterIndex + 1), inorder.slice(0, delimiterIndex))
|
||||
root.right = buildTree(preorder.slice(delimiterIndex + 1, preorder.size), inorder.slice(delimiterIndex + 1, len))
|
||||
|
||||
root
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -488,6 +488,46 @@ func minDepth(_ root: TreeNode?) -> Int {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Scala
|
||||
|
||||
递归法:
|
||||
```scala
|
||||
object Solution {
|
||||
def minDepth(root: TreeNode): Int = {
|
||||
if (root == null) return 0
|
||||
if (root.left == null && root.right != null) return 1 + minDepth(root.right)
|
||||
if (root.left != null && root.right == null) return 1 + minDepth(root.left)
|
||||
// 如果两侧都不为空,则取最小值,return关键字可以省略
|
||||
1 + math.min(minDepth(root.left), minDepth(root.right))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
迭代法:
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def minDepth(root: TreeNode): Int = {
|
||||
if (root == null) return 0
|
||||
var depth = 0
|
||||
val queue = mutable.Queue[TreeNode]()
|
||||
queue.enqueue(root)
|
||||
while (!queue.isEmpty) {
|
||||
depth += 1
|
||||
val len = queue.size
|
||||
for (i <- 0 until len) {
|
||||
val curNode = queue.dequeue()
|
||||
if (curNode.left != null) queue.enqueue(curNode.left)
|
||||
if (curNode.right != null) queue.enqueue(curNode.right)
|
||||
if (curNode.left == null && curNode.right == null) return depth
|
||||
}
|
||||
}
|
||||
depth
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
rust:
|
||||
```rust
|
||||
impl Solution {
|
||||
@ -550,6 +590,7 @@ impl Solution {
|
||||
}
|
||||
min_depth
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
-----------------------
|
||||
|
@ -300,7 +300,7 @@ public:
|
||||
|
||||
## java
|
||||
|
||||
lc112
|
||||
### 0112.路径总和
|
||||
```java
|
||||
class solution {
|
||||
public boolean haspathsum(treenode root, int targetsum) {
|
||||
@ -373,7 +373,7 @@ class solution {
|
||||
|
||||
```
|
||||
|
||||
0113.路径总和-ii
|
||||
### 0113.路径总和-ii
|
||||
|
||||
```java
|
||||
class solution {
|
||||
@ -436,7 +436,7 @@ class Solution {
|
||||
|
||||
## python
|
||||
|
||||
0112.路径总和
|
||||
### 0112.路径总和
|
||||
|
||||
**递归**
|
||||
```python
|
||||
@ -488,7 +488,7 @@ class solution:
|
||||
return false
|
||||
```
|
||||
|
||||
0113.路径总和-ii
|
||||
### 0113.路径总和-ii
|
||||
|
||||
**递归**
|
||||
```python
|
||||
@ -545,7 +545,7 @@ class Solution:
|
||||
|
||||
## go
|
||||
|
||||
112. 路径总和
|
||||
### 112. 路径总和
|
||||
|
||||
```go
|
||||
//递归法
|
||||
@ -570,7 +570,7 @@ func hasPathSum(root *TreeNode, targetSum int) bool {
|
||||
}
|
||||
```
|
||||
|
||||
113. 路径总和 II
|
||||
### 113. 路径总和 II
|
||||
|
||||
```go
|
||||
/**
|
||||
@ -612,7 +612,7 @@ func traverse(node *TreeNode, result *[][]int, currPath *[]int, targetSum int) {
|
||||
|
||||
## javascript
|
||||
|
||||
0112.路径总和
|
||||
### 0112.路径总和
|
||||
|
||||
**递归**
|
||||
```javascript
|
||||
@ -673,7 +673,7 @@ let hasPathSum = function(root, targetSum) {
|
||||
};
|
||||
```
|
||||
|
||||
0113.路径总和-ii
|
||||
### 0113.路径总和-ii
|
||||
|
||||
**递归**
|
||||
```javascript
|
||||
@ -768,7 +768,7 @@ let pathSum = function(root, targetSum) {
|
||||
|
||||
## TypeScript
|
||||
|
||||
> 0112.路径总和
|
||||
### 0112.路径总和
|
||||
|
||||
**递归法:**
|
||||
|
||||
@ -850,7 +850,7 @@ function hasPathSum(root: TreeNode | null, targetSum: number): boolean {
|
||||
};
|
||||
```
|
||||
|
||||
> 0112.路径总和 ii
|
||||
### 0112.路径总和 ii
|
||||
|
||||
**递归法:**
|
||||
|
||||
@ -888,7 +888,7 @@ function pathSum(root: TreeNode | null, targetSum: number): number[][] {
|
||||
|
||||
## Swift
|
||||
|
||||
0112.路径总和
|
||||
### 0112.路径总和
|
||||
|
||||
**递归**
|
||||
|
||||
@ -955,7 +955,7 @@ func hasPathSum(_ root: TreeNode?, _ targetSum: Int) -> Bool {
|
||||
}
|
||||
```
|
||||
|
||||
0113.路径总和 II
|
||||
### 0113.路径总和 II
|
||||
|
||||
**递归**
|
||||
|
||||
@ -1126,7 +1126,90 @@ int** pathSum(struct TreeNode* root, int targetSum, int* returnSize, int** retur
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
|
||||
### 0112.路径总和
|
||||
|
||||
**递归:**
|
||||
```scala
|
||||
object Solution {
|
||||
def hasPathSum(root: TreeNode, targetSum: Int): Boolean = {
|
||||
if(root == null) return false
|
||||
var res = false
|
||||
|
||||
def traversal(curNode: TreeNode, sum: Int): Unit = {
|
||||
if (res) return // 如果直接标记为true了,就没有往下递归的必要了
|
||||
if (curNode.left == null && curNode.right == null && sum == targetSum) {
|
||||
res = true
|
||||
return
|
||||
}
|
||||
// 往下递归
|
||||
if (curNode.left != null) traversal(curNode.left, sum + curNode.left.value)
|
||||
if (curNode.right != null) traversal(curNode.right, sum + curNode.right.value)
|
||||
}
|
||||
|
||||
traversal(root, root.value)
|
||||
res // return关键字可以省略
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**迭代:**
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def hasPathSum(root: TreeNode, targetSum: Int): Boolean = {
|
||||
if (root == null) return false
|
||||
val stack = mutable.Stack[(TreeNode, Int)]()
|
||||
stack.push((root, root.value)) // 将根节点元素放入stack
|
||||
while (!stack.isEmpty) {
|
||||
val curNode = stack.pop() // 取出栈顶元素
|
||||
// 如果遇到叶子节点,看当前的值是否等于targetSum,等于则返回true
|
||||
if (curNode._1.left == null && curNode._1.right == null && curNode._2 == targetSum) {
|
||||
return true
|
||||
}
|
||||
if (curNode._1.right != null) stack.push((curNode._1.right, curNode._2 + curNode._1.right.value))
|
||||
if (curNode._1.left != null) stack.push((curNode._1.left, curNode._2 + curNode._1.left.value))
|
||||
}
|
||||
false //如果没有返回true,即可返回false,return关键字可以省略
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 0113.路径总和 II
|
||||
|
||||
**递归:**
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable.ListBuffer
|
||||
def pathSum(root: TreeNode, targetSum: Int): List[List[Int]] = {
|
||||
val res = ListBuffer[List[Int]]()
|
||||
if (root == null) return res.toList
|
||||
val path = ListBuffer[Int]();
|
||||
|
||||
def traversal(cur: TreeNode, count: Int): Unit = {
|
||||
if (cur.left == null && cur.right == null && count == 0) {
|
||||
res.append(path.toList)
|
||||
return
|
||||
}
|
||||
if (cur.left != null) {
|
||||
path.append(cur.left.value)
|
||||
traversal(cur.left, count - cur.left.value)
|
||||
path.remove(path.size - 1)
|
||||
}
|
||||
if (cur.right != null) {
|
||||
path.append(cur.right.value)
|
||||
traversal(cur.right, count - cur.right.value)
|
||||
path.remove(path.size - 1)
|
||||
}
|
||||
}
|
||||
|
||||
path.append(root.value)
|
||||
traversal(root, targetSum - root.value)
|
||||
res.toList
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -442,7 +442,7 @@ var partition = function(s) {
|
||||
}
|
||||
for(let j = i; j < len; j++) {
|
||||
if(!isPalindrome(s, i, j)) continue;
|
||||
path.push(s.substr(i, j - i + 1));
|
||||
path.push(s.slice(i, j + 1));
|
||||
backtracking(j + 1);
|
||||
path.pop();
|
||||
}
|
||||
|
@ -817,6 +817,53 @@ object Solution {
|
||||
```
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
function reverseWords($s) {
|
||||
$this->removeExtraSpaces($s);
|
||||
$this->reverseString($s, 0, strlen($s)-1);
|
||||
// 将每个单词反转
|
||||
$start = 0;
|
||||
for ($i = 0; $i <= strlen($s); $i++) {
|
||||
// 到达空格或者串尾,说明一个单词结束。进行翻转。
|
||||
if ($i == strlen($s) || $s[$i] == ' ') {
|
||||
// 翻转,注意是左闭右闭 []的翻转。
|
||||
$this->reverseString($s, $start, $i-1);
|
||||
// +1: 单词与单词直接有个空格
|
||||
$start = $i + 1;
|
||||
}
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
// 移除多余空格
|
||||
function removeExtraSpaces(&$s){
|
||||
$slow = 0;
|
||||
for ($i = 0; $i < strlen($s); $i++) {
|
||||
if ($s[$i] != ' ') {
|
||||
if ($slow != 0){
|
||||
$s[$slow++] = ' ';
|
||||
}
|
||||
while ($i < strlen($s) && $s[$i] != ' ') {
|
||||
$s[$slow++] = $s[$i++];
|
||||
}
|
||||
}
|
||||
}
|
||||
// 移动覆盖处理,丢弃多余的脏数据。
|
||||
$s = substr($s,0,$slow);
|
||||
return ;
|
||||
}
|
||||
|
||||
// 翻转字符串
|
||||
function reverseString(&$s, $start, $end) {
|
||||
for ($i = $start, $j = $end; $i < $j; $i++, $j--) {
|
||||
$tmp = $s[$i];
|
||||
$s[$i] = $s[$j];
|
||||
$s[$j] = $tmp;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -496,8 +496,26 @@ struct ListNode* reverseList(struct ListNode* head){
|
||||
return reverse(NULL, head);
|
||||
}
|
||||
```
|
||||
Scala:
|
||||
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
// 双指针法:
|
||||
function reverseList($head) {
|
||||
$cur = $head;
|
||||
$pre = NULL;
|
||||
while($cur){
|
||||
$temp = $cur->next;
|
||||
$cur->next = $pre;
|
||||
$pre = $cur;
|
||||
$cur = $temp;
|
||||
}
|
||||
return $pre;
|
||||
}
|
||||
```
|
||||
|
||||
Scala:
|
||||
双指针法:
|
||||
```scala
|
||||
object Solution {
|
||||
@ -529,6 +547,7 @@ object Solution {
|
||||
cur.next = pre
|
||||
reverse(cur, tmp) // 此时cur成为前一个节点,tmp是当前节点
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
-----------------------
|
||||
|
@ -360,39 +360,30 @@ func backTree(n,k,startIndex int,track *[]int,result *[][]int){
|
||||
## javaScript
|
||||
|
||||
```js
|
||||
// 等差数列
|
||||
var maxV = k => k * (9 + 10 - k) / 2;
|
||||
var minV = k => k * (1 + k) / 2;
|
||||
/**
|
||||
* @param {number} k
|
||||
* @param {number} n
|
||||
* @return {number[][]}
|
||||
*/
|
||||
var combinationSum3 = function(k, n) {
|
||||
if (k > 9 || k < 1) return [];
|
||||
// if (n > maxV(k) || n < minV(k)) return [];
|
||||
// if (n === maxV(k)) return [Array.from({length: k}).map((v, i) => 9 - i)];
|
||||
// if (n === minV(k)) return [Array.from({length: k}).map((v, i) => i + 1)];
|
||||
|
||||
const res = [], path = [];
|
||||
backtracking(k, n, 1, 0);
|
||||
return res;
|
||||
function backtracking(k, n, i, sum){
|
||||
const len = path.length;
|
||||
if (len > k || sum > n) return;
|
||||
if (maxV(k - len) < n - sum) return;
|
||||
if (minV(k - len) > n - sum) return;
|
||||
|
||||
if(len === k && sum == n) {
|
||||
res.push(Array.from(path));
|
||||
const backtrack = (start) => {
|
||||
const l = path.length;
|
||||
if (l === k) {
|
||||
const sum = path.reduce((a, b) => a + b);
|
||||
if (sum === n) {
|
||||
res.push([...path]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const min = Math.min(n - sum, 9 + len - k + 1);
|
||||
|
||||
for(let a = i; a <= min; a++) {
|
||||
path.push(a);
|
||||
sum += a;
|
||||
backtracking(k, n, a + 1, sum);
|
||||
for (let i = start; i <= 9 - (k - l) + 1; i++) {
|
||||
path.push(i);
|
||||
backtrack(i + 1);
|
||||
path.pop();
|
||||
sum -= a;
|
||||
}
|
||||
}
|
||||
let res = [], path = [];
|
||||
backtrack(1);
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -646,5 +646,68 @@ func countNodes(_ root: TreeNode?) -> Int {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
|
||||
递归:
|
||||
```scala
|
||||
object Solution {
|
||||
def countNodes(root: TreeNode): Int = {
|
||||
if(root == null) return 0
|
||||
1 + countNodes(root.left) + countNodes(root.right)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
层序遍历:
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def countNodes(root: TreeNode): Int = {
|
||||
if (root == null) return 0
|
||||
val queue = mutable.Queue[TreeNode]()
|
||||
var node = 0
|
||||
queue.enqueue(root)
|
||||
while (!queue.isEmpty) {
|
||||
val len = queue.size
|
||||
for (i <- 0 until len) {
|
||||
node += 1
|
||||
val curNode = queue.dequeue()
|
||||
if (curNode.left != null) queue.enqueue(curNode.left)
|
||||
if (curNode.right != null) queue.enqueue(curNode.right)
|
||||
}
|
||||
}
|
||||
node
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
利用完全二叉树性质:
|
||||
```scala
|
||||
object Solution {
|
||||
def countNodes(root: TreeNode): Int = {
|
||||
if (root == null) return 0
|
||||
var leftNode = root.left
|
||||
var rightNode = root.right
|
||||
// 向左向右往下探
|
||||
var leftDepth = 0
|
||||
while (leftNode != null) {
|
||||
leftDepth += 1
|
||||
leftNode = leftNode.left
|
||||
}
|
||||
var rightDepth = 0
|
||||
while (rightNode != null) {
|
||||
rightDepth += 1
|
||||
rightNode = rightNode.right
|
||||
}
|
||||
// 如果相等就是一个满二叉树
|
||||
if (leftDepth == rightDepth) {
|
||||
return (2 << leftDepth) - 1
|
||||
}
|
||||
// 如果不相等就不是一个完全二叉树,继续向下递归
|
||||
countNodes(root.left) + countNodes(root.right) + 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -702,5 +702,35 @@ func binaryTreePaths(_ root: TreeNode?) -> [String] {
|
||||
}
|
||||
```
|
||||
|
||||
Scala:
|
||||
|
||||
递归:
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable.ListBuffer
|
||||
def binaryTreePaths(root: TreeNode): List[String] = {
|
||||
val res = ListBuffer[String]()
|
||||
def traversal(curNode: TreeNode, path: ListBuffer[Int]): Unit = {
|
||||
path.append(curNode.value)
|
||||
if (curNode.left == null && curNode.right == null) {
|
||||
res.append(path.mkString("->")) // mkString函数: 将数组的所有值按照指定字符串拼接
|
||||
return // 处理完可以直接return
|
||||
}
|
||||
|
||||
if (curNode.left != null) {
|
||||
traversal(curNode.left, path)
|
||||
path.remove(path.size - 1)
|
||||
}
|
||||
if (curNode.right != null) {
|
||||
traversal(curNode.right, path)
|
||||
path.remove(path.size - 1)
|
||||
}
|
||||
}
|
||||
traversal(root, ListBuffer[Int]())
|
||||
res.toList
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -266,6 +266,38 @@ public class Solution
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
// 双指针
|
||||
// 一:
|
||||
function reverseString(&$s) {
|
||||
$left = 0;
|
||||
$right = count($s)-1;
|
||||
while($left<$right){
|
||||
$temp = $s[$left];
|
||||
$s[$left] = $s[$right];
|
||||
$s[$right] = $temp;
|
||||
$left++;
|
||||
$right--;
|
||||
}
|
||||
}
|
||||
|
||||
// 二:
|
||||
function reverseString(&$s) {
|
||||
$this->reverse($s,0,count($s)-1);
|
||||
}
|
||||
// 按指定位置交换元素
|
||||
function reverse(&$s, $start, $end) {
|
||||
for ($i = $start, $j = $end; $i < $j; $i++, $j--) {
|
||||
$tmp = $s[$i];
|
||||
$s[$i] = $s[$j];
|
||||
$s[$j] = $tmp;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Scala:
|
||||
```scala
|
||||
object Solution {
|
||||
|
@ -516,6 +516,44 @@ int sumOfLeftLeaves(struct TreeNode* root){
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
|
||||
**递归:**
|
||||
```scala
|
||||
object Solution {
|
||||
def sumOfLeftLeaves(root: TreeNode): Int = {
|
||||
if(root == null) return 0
|
||||
var midValue = 0
|
||||
if(root.left != null && root.left.left == null && root.left.right == null){
|
||||
midValue = root.left.value
|
||||
}
|
||||
// return关键字可以省略
|
||||
midValue + sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**迭代:**
|
||||
```scala
|
||||
object Solution {
|
||||
import scala.collection.mutable
|
||||
def sumOfLeftLeaves(root: TreeNode): Int = {
|
||||
val stack = mutable.Stack[TreeNode]()
|
||||
if (root == null) return 0
|
||||
stack.push(root)
|
||||
var sum = 0
|
||||
while (!stack.isEmpty) {
|
||||
val curNode = stack.pop()
|
||||
if (curNode.left != null && curNode.left.left == null && curNode.left.right == null) {
|
||||
sum += curNode.left.value // 如果满足条件就累加
|
||||
}
|
||||
if (curNode.right != null) stack.push(curNode.right)
|
||||
if (curNode.left != null) stack.push(curNode.left)
|
||||
}
|
||||
sum
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -417,6 +417,26 @@ var canPartition = function(nums) {
|
||||
```
|
||||
|
||||
|
||||
TypeScript:
|
||||
|
||||
```ts
|
||||
function canPartition(nums: number[]): boolean {
|
||||
const sum: number = nums.reduce((a: number, b: number): number => a + b);
|
||||
if (sum % 2 === 1) return false;
|
||||
const target: number = sum / 2;
|
||||
// dp[j]表示容量(总数和)为j的背包所能装下的数(下标[0, i]之间任意取)的总和(<= 容量)的最大值
|
||||
const dp: number[] = new Array(target + 1).fill(0);
|
||||
const n: number = nums.length;
|
||||
for (let i: number = 0; i < n; i++) {
|
||||
for (let j: number = target; j >= nums[i]; j--) {
|
||||
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
|
||||
}
|
||||
}
|
||||
return dp[target] === target;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
C:
|
||||
二维dp:
|
||||
```c
|
||||
@ -575,6 +595,5 @@ function canPartition(nums: number[]): boolean {
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -351,22 +351,26 @@ const findTargetSumWays = (nums, target) => {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
```typescript
|
||||
TypeScript:
|
||||
|
||||
```ts
|
||||
function findTargetSumWays(nums: number[], target: number): number {
|
||||
const sum: number = nums.reduce((pre, cur) => pre + cur);
|
||||
if (Math.abs(target) > sum) return 0;
|
||||
if ((target + sum) % 2 === 1) return 0;
|
||||
const bagSize: number = (target + sum) / 2;
|
||||
const dp: number[] = new Array(bagSize + 1).fill(0);
|
||||
dp[0] = 1;
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
for (let j = bagSize; j >= nums[i]; j--) {
|
||||
// 把数组分成两个组合left, right.left + right = sum, left - right = target.
|
||||
const sum: number = nums.reduce((a: number, b: number): number => a + b);
|
||||
if ((sum + target) % 2 || Math.abs(target) > sum) return 0;
|
||||
const left: number = (sum + target) / 2;
|
||||
|
||||
// 将问题转化为装满容量为left的背包有多少种方法
|
||||
// dp[i]表示装满容量为i的背包有多少种方法
|
||||
const dp: number[] = new Array(left + 1).fill(0);
|
||||
dp[0] = 1; // 装满容量为0的背包有1种方法(什么也不装)
|
||||
for (let i: number = 0; i < nums.length; i++) {
|
||||
for (let j: number = left; j >= nums[i]; j--) {
|
||||
dp[j] += dp[j - nums[i]];
|
||||
}
|
||||
}
|
||||
return dp[bagSize];
|
||||
return dp[left];
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -332,5 +332,36 @@ var nextGreaterElement = function (nums1, nums2) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
```typescript
|
||||
function nextGreaterElement(nums1: number[], nums2: number[]): number[] {
|
||||
const resArr: number[] = new Array(nums1.length).fill(-1);
|
||||
const stack: number[] = [];
|
||||
const helperMap: Map<number, number> = new Map();
|
||||
nums1.forEach((num, index) => {
|
||||
helperMap.set(num, index);
|
||||
})
|
||||
stack.push(0);
|
||||
for (let i = 1, length = nums2.length; i < length; i++) {
|
||||
let top = stack[stack.length - 1];
|
||||
while (stack.length > 0 && nums2[top] < nums2[i]) {
|
||||
let index = helperMap.get(nums2[top]);
|
||||
if (index !== undefined) {
|
||||
resArr[index] = nums2[i];
|
||||
}
|
||||
stack.pop();
|
||||
top = stack[stack.length - 1];
|
||||
}
|
||||
if (helperMap.get(nums2[i]) !== undefined) {
|
||||
stack.push(i);
|
||||
}
|
||||
}
|
||||
return resArr;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -182,5 +182,31 @@ var nextGreaterElements = function (nums) {
|
||||
return res;
|
||||
};
|
||||
```
|
||||
TypeScript:
|
||||
|
||||
```typescript
|
||||
function nextGreaterElements(nums: number[]): number[] {
|
||||
const length: number = nums.length;
|
||||
const stack: number[] = [];
|
||||
stack.push(0);
|
||||
const resArr: number[] = new Array(length).fill(-1);
|
||||
for (let i = 1; i < length * 2; i++) {
|
||||
const index = i % length;
|
||||
let top = stack[stack.length - 1];
|
||||
while (stack.length > 0 && nums[top] < nums[index]) {
|
||||
resArr[top] = nums[index];
|
||||
stack.pop();
|
||||
top = stack[stack.length - 1];
|
||||
}
|
||||
if (i < length) {
|
||||
stack.push(i);
|
||||
}
|
||||
}
|
||||
return resArr;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -546,7 +546,50 @@ func findBottomLeftValue(_ root: TreeNode?) -> Int {
|
||||
}
|
||||
```
|
||||
|
||||
## Scala
|
||||
|
||||
递归版本:
|
||||
```scala
|
||||
object Solution {
|
||||
def findBottomLeftValue(root: TreeNode): Int = {
|
||||
var maxLeftValue = 0
|
||||
var maxLen = Int.MinValue
|
||||
// 递归方法
|
||||
def traversal(node: TreeNode, leftLen: Int): Unit = {
|
||||
// 如果左右都为空并且当前深度大于最大深度,记录最左节点的值
|
||||
if (node.left == null && node.right == null && leftLen > maxLen) {
|
||||
maxLen = leftLen
|
||||
maxLeftValue = node.value
|
||||
}
|
||||
if (node.left != null) traversal(node.left, leftLen + 1)
|
||||
if (node.right != null) traversal(node.right, leftLen + 1)
|
||||
}
|
||||
traversal(root, 0) // 调用方法
|
||||
maxLeftValue // return关键字可以省略
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
层序遍历:
|
||||
```scala
|
||||
import scala.collection.mutable
|
||||
|
||||
def findBottomLeftValue(root: TreeNode): Int = {
|
||||
val queue = mutable.Queue[TreeNode]()
|
||||
queue.enqueue(root)
|
||||
var res = 0 // 记录每层最左侧结果
|
||||
while (!queue.isEmpty) {
|
||||
val len = queue.size
|
||||
for (i <- 0 until len) {
|
||||
val curNode = queue.dequeue()
|
||||
if (i == 0) res = curNode.value // 记录最最左侧的节点
|
||||
if (curNode.left != null) queue.enqueue(curNode.left)
|
||||
if (curNode.right != null) queue.enqueue(curNode.right)
|
||||
}
|
||||
}
|
||||
res // 最终返回结果,return关键字可以省略
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -235,6 +235,35 @@ const longestPalindromeSubseq = (s) => {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
```typescript
|
||||
function longestPalindromeSubseq(s: string): number {
|
||||
/**
|
||||
dp[i][j]:[i,j]区间内,最长回文子序列的长度
|
||||
*/
|
||||
const length: number = s.length;
|
||||
const dp: number[][] = new Array(length).fill(0)
|
||||
.map(_ => new Array(length).fill(0));
|
||||
for (let i = 0; i < length; i++) {
|
||||
dp[i][i] = 1;
|
||||
}
|
||||
// 自下而上,自左往右遍历
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
for (let j = i + 1; j < length; j++) {
|
||||
if (s[i] === s[j]) {
|
||||
dp[i][j] = dp[i + 1][j - 1] + 2;
|
||||
} else {
|
||||
dp[i][j] = Math.max(dp[i][j - 1], dp[i + 1][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[0][length - 1];
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -406,6 +406,63 @@ const countSubstrings = (s) => {
|
||||
}
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
> 动态规划:
|
||||
|
||||
```typescript
|
||||
function countSubstrings(s: string): number {
|
||||
/**
|
||||
dp[i][j]: [i,j]区间内的字符串是否为回文(左闭右闭)
|
||||
*/
|
||||
const length: number = s.length;
|
||||
const dp: boolean[][] = new Array(length).fill(0)
|
||||
.map(_ => new Array(length).fill(false));
|
||||
let resCount: number = 0;
|
||||
// 自下而上,自左向右遍历
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
for (let j = i; j < length; j++) {
|
||||
if (
|
||||
s[i] === s[j] &&
|
||||
(j - i <= 1 || dp[i + 1][j - 1] === true)
|
||||
) {
|
||||
dp[i][j] = true;
|
||||
resCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return resCount;
|
||||
};
|
||||
```
|
||||
|
||||
> 双指针法:
|
||||
|
||||
```typescript
|
||||
function countSubstrings(s: string): number {
|
||||
const length: number = s.length;
|
||||
let resCount: number = 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
resCount += expandRange(s, i, i);
|
||||
resCount += expandRange(s, i, i + 1);
|
||||
}
|
||||
return resCount;
|
||||
};
|
||||
function expandRange(s: string, left: number, right: number): number {
|
||||
let palindromeNum: number = 0;
|
||||
while (
|
||||
left >= 0 && right < s.length &&
|
||||
s[left] === s[right]
|
||||
) {
|
||||
palindromeNum++;
|
||||
left--;
|
||||
right++;
|
||||
}
|
||||
return palindromeNum;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -372,6 +372,32 @@ var dailyTemperatures = function(temperatures) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
> 精简版:
|
||||
|
||||
```typescript
|
||||
function dailyTemperatures(temperatures: number[]): number[] {
|
||||
const length: number = temperatures.length;
|
||||
const stack: number[] = [];
|
||||
const resArr: number[] = new Array(length).fill(0);
|
||||
stack.push(0);
|
||||
for (let i = 1; i < length; i++) {
|
||||
let top = stack[stack.length - 1];
|
||||
while (
|
||||
stack.length > 0 &&
|
||||
temperatures[top] < temperatures[i]
|
||||
) {
|
||||
resArr[top] = i - top;
|
||||
stack.pop();
|
||||
top = stack[stack.length - 1];
|
||||
}
|
||||
stack.push(i);
|
||||
}
|
||||
return resArr;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -157,6 +157,26 @@ var validMountainArray = function(arr) {
|
||||
};
|
||||
```
|
||||
|
||||
## TypeScript
|
||||
|
||||
```typescript
|
||||
function validMountainArray(arr: number[]): boolean {
|
||||
const length: number = arr.length;
|
||||
if (length < 3) return false;
|
||||
let left: number = 0,
|
||||
right: number = length - 1;
|
||||
while (left < (length - 1) && arr[left] < arr[left + 1]) {
|
||||
left++;
|
||||
}
|
||||
while (right > 0 && arr[right] < arr[right - 1]) {
|
||||
right--;
|
||||
}
|
||||
if (left === right && left !== 0 && right !== length - 1)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -277,26 +277,29 @@ var lastStoneWeightII = function (stones) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
```typescript
|
||||
TypeScript版本
|
||||
|
||||
```ts
|
||||
function lastStoneWeightII(stones: number[]): number {
|
||||
const sum: number = stones.reduce((pre, cur) => pre + cur);
|
||||
const bagSize: number = Math.floor(sum / 2);
|
||||
const weightArr: number[] = stones;
|
||||
const valueArr: number[] = stones;
|
||||
const goodsNum: number = weightArr.length;
|
||||
const dp: number[] = new Array(bagSize + 1).fill(0);
|
||||
for (let i = 0; i < goodsNum; i++) {
|
||||
for (let j = bagSize; j >= weightArr[i]; j--) {
|
||||
dp[j] = Math.max(dp[j], dp[j - weightArr[i]] + valueArr[i]);
|
||||
const sum: number = stones.reduce((a: number, b:number): number => a + b);
|
||||
const target: number = Math.floor(sum / 2);
|
||||
const n: number = stones.length;
|
||||
// dp[j]表示容量(总数和)为j的背包所能装下的数(下标[0, i]之间任意取)的总和(<= 容量)的最大值
|
||||
const dp: number[] = new Array(target + 1).fill(0);
|
||||
for (let i: number = 0; i < n; i++ ) {
|
||||
for (let j: number = target; j >= stones[i]; j--) {
|
||||
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
|
||||
}
|
||||
}
|
||||
return sum - dp[bagSize] * 2;
|
||||
return sum - dp[target] - dp[target];
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -150,5 +150,39 @@ var uniqueOccurrences = function(arr) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
> 借用数组:
|
||||
|
||||
```typescript
|
||||
function uniqueOccurrences(arr: number[]): boolean {
|
||||
const countArr: number[] = new Array(2001).fill(0);
|
||||
for (let i = 0, length = arr.length; i < length; i++) {
|
||||
countArr[arr[i] + 1000]++;
|
||||
}
|
||||
const flagArr: boolean[] = new Array(1001).fill(false);
|
||||
for (let count of countArr) {
|
||||
if (count === 0) continue;
|
||||
if (flagArr[count] === true) return false;
|
||||
flagArr[count] = true;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
> 借用map、set
|
||||
|
||||
```typescript
|
||||
function uniqueOccurrences(arr: number[]): boolean {
|
||||
const countMap: Map<number, number> = new Map();
|
||||
arr.forEach(val => {
|
||||
countMap.set(val, (countMap.get(val) || 0) + 1);
|
||||
})
|
||||
return countMap.size === new Set(countMap.values()).size;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||
|
@ -217,6 +217,46 @@ var smallerNumbersThanCurrent = function(nums) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
> 暴力法:
|
||||
|
||||
```typescript
|
||||
function smallerNumbersThanCurrent(nums: number[]): number[] {
|
||||
const length: number = nums.length;
|
||||
const resArr: number[] = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
let count: number = 0;
|
||||
for (let j = 0; j < length; j++) {
|
||||
if (nums[j] < nums[i]) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
resArr[i] = count;
|
||||
}
|
||||
return resArr;
|
||||
};
|
||||
```
|
||||
|
||||
> 排序+hash
|
||||
|
||||
```typescript
|
||||
function smallerNumbersThanCurrent(nums: number[]): number[] {
|
||||
const length: number = nums.length;
|
||||
const sortedArr: number[] = [...nums];
|
||||
sortedArr.sort((a, b) => a - b);
|
||||
const hashMap: Map<number, number> = new Map();
|
||||
for (let i = length - 1; i >= 0; i--) {
|
||||
hashMap.set(sortedArr[i], i);
|
||||
}
|
||||
const resArr: number[] = [];
|
||||
for (let i = 0; i < length; i++) {
|
||||
resArr[i] = hashMap.get(nums[i]);
|
||||
}
|
||||
return resArr;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -467,6 +467,42 @@ object Solution {
|
||||
def replaceSpace(s: String): String = {
|
||||
s.map(c => if(c == ' ') "%20" else c).mkString
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
PHP:
|
||||
```php
|
||||
function replaceSpace($s){
|
||||
$sLen = strlen($s);
|
||||
$moreLen = $this->spaceLen($s) * 2;
|
||||
|
||||
$head = $sLen - 1;
|
||||
$tail = $sLen + $moreLen - 1;
|
||||
|
||||
$s = $s . str_repeat(' ', $moreLen);
|
||||
while ($head != $tail) {
|
||||
if ($s[$head] == ' ') {
|
||||
$s[$tail--] = '0';
|
||||
$s[$tail--] = '2';
|
||||
$s[$tail] = '%';
|
||||
} else {
|
||||
$s[$tail] = $s[$head];
|
||||
}
|
||||
$head--;
|
||||
$tail--;
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
// 统计空格个数
|
||||
function spaceLen($s){
|
||||
$count = 0;
|
||||
for ($i = 0; $i < strlen($s); $i++) {
|
||||
if ($s[$i] == ' ') {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -365,6 +365,84 @@ class Solution:
|
||||
return res
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
|
||||
**90.子集II**
|
||||
|
||||
```javascript
|
||||
function subsetsWithDup(nums) {
|
||||
nums.sort((a, b) => a - b);
|
||||
const resArr = [];
|
||||
backTraking(nums, 0, []);
|
||||
return resArr;
|
||||
function backTraking(nums, startIndex, route) {
|
||||
resArr.push([...route]);
|
||||
const helperSet = new Set();
|
||||
for (let i = startIndex, length = nums.length; i < length; i++) {
|
||||
if (helperSet.has(nums[i])) continue;
|
||||
helperSet.add(nums[i]);
|
||||
route.push(nums[i]);
|
||||
backTraking(nums, i + 1, route);
|
||||
route.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**40. 组合总和 II**
|
||||
|
||||
```javascript
|
||||
function combinationSum2(candidates, target) {
|
||||
candidates.sort((a, b) => a - b);
|
||||
const resArr = [];
|
||||
backTracking(candidates, target, 0, 0, []);
|
||||
return resArr;
|
||||
function backTracking( candidates, target, curSum, startIndex, route ) {
|
||||
if (curSum > target) return;
|
||||
if (curSum === target) {
|
||||
resArr.push([...route]);
|
||||
return;
|
||||
}
|
||||
const helperSet = new Set();
|
||||
for (let i = startIndex, length = candidates.length; i < length; i++) {
|
||||
let tempVal = candidates[i];
|
||||
if (helperSet.has(tempVal)) continue;
|
||||
helperSet.add(tempVal);
|
||||
route.push(tempVal);
|
||||
backTracking(candidates, target, curSum + tempVal, i + 1, route);
|
||||
route.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**47. 全排列 II**
|
||||
|
||||
```javaescript
|
||||
function permuteUnique(nums) {
|
||||
const resArr = [];
|
||||
const usedArr = [];
|
||||
backTracking(nums, []);
|
||||
return resArr;
|
||||
function backTracking(nums, route) {
|
||||
if (nums.length === route.length) {
|
||||
resArr.push([...route]);
|
||||
return;
|
||||
}
|
||||
const usedSet = new Set();
|
||||
for (let i = 0, length = nums.length; i < length; i++) {
|
||||
if (usedArr[i] === true || usedSet.has(nums[i])) continue;
|
||||
usedSet.add(nums[i]);
|
||||
route.push(nums[i]);
|
||||
usedArr[i] = true;
|
||||
backTracking(nums, route);
|
||||
usedArr[i] = false;
|
||||
route.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
**90.子集II**
|
||||
@ -376,7 +454,7 @@ function subsetsWithDup(nums: number[]): number[][] {
|
||||
backTraking(nums, 0, []);
|
||||
return resArr;
|
||||
function backTraking(nums: number[], startIndex: number, route: number[]): void {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
const helperSet: Set<number> = new Set();
|
||||
for (let i = startIndex, length = nums.length; i < length; i++) {
|
||||
if (helperSet.has(nums[i])) continue;
|
||||
@ -403,7 +481,7 @@ function combinationSum2(candidates: number[], target: number): number[][] {
|
||||
) {
|
||||
if (curSum > target) return;
|
||||
if (curSum === target) {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
return;
|
||||
}
|
||||
const helperSet: Set<number> = new Set();
|
||||
@ -430,7 +508,7 @@ function permuteUnique(nums: number[]): number[][] {
|
||||
return resArr;
|
||||
function backTracking(nums: number[], route: number[]): void {
|
||||
if (nums.length === route.length) {
|
||||
resArr.push(route.slice());
|
||||
resArr.push([...route]);
|
||||
return;
|
||||
}
|
||||
const usedSet: Set<number> = new Set();
|
||||
|
Reference in New Issue
Block a user