mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 03:34:02 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
BIN
pics/.DS_Store
vendored
BIN
pics/.DS_Store
vendored
Binary file not shown.
@ -439,6 +439,55 @@ var solveSudoku = function(board) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
/**
|
||||||
|
Do not return anything, modify board in-place instead.
|
||||||
|
*/
|
||||||
|
function isValid(col: number, row: number, val: string, board: string[][]): boolean {
|
||||||
|
let n: number = board.length;
|
||||||
|
// 列向检查
|
||||||
|
for (let rowIndex = 0; rowIndex < n; rowIndex++) {
|
||||||
|
if (board[rowIndex][col] === val) return false;
|
||||||
|
}
|
||||||
|
// 横向检查
|
||||||
|
for (let colIndex = 0; colIndex < n; colIndex++) {
|
||||||
|
if (board[row][colIndex] === val) return false;
|
||||||
|
}
|
||||||
|
// 九宫格检查
|
||||||
|
const startX = Math.floor(col / 3) * 3;
|
||||||
|
const startY = Math.floor(row / 3) * 3;
|
||||||
|
for (let rowIndex = startY; rowIndex < startY + 3; rowIndex++) {
|
||||||
|
for (let colIndex = startX; colIndex < startX + 3; colIndex++) {
|
||||||
|
if (board[rowIndex][colIndex] === val) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function solveSudoku(board: string[][]): void {
|
||||||
|
let n: number = 9;
|
||||||
|
backTracking(n, board);
|
||||||
|
function backTracking(n: number, board: string[][]): boolean {
|
||||||
|
for (let row = 0; row < n; row++) {
|
||||||
|
for (let col = 0; col < n; col++) {
|
||||||
|
if (board[row][col] === '.') {
|
||||||
|
for (let i = 1; i <= n; i++) {
|
||||||
|
if (isValid(col, row, String(i), board)) {
|
||||||
|
board[row][col] = String(i);
|
||||||
|
if (backTracking(n, board) === true) return true;
|
||||||
|
board[row][col] = '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### C
|
### C
|
||||||
|
|
||||||
```C
|
```C
|
||||||
|
@ -331,6 +331,34 @@ var permute = function(nums) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function permute(nums: number[]): number[][] {
|
||||||
|
const resArr: number[][] = [];
|
||||||
|
const helperSet: Set<number> = new Set();
|
||||||
|
backTracking(nums, []);
|
||||||
|
return resArr;
|
||||||
|
function backTracking(nums: number[], route: number[]): void {
|
||||||
|
if (route.length === nums.length) {
|
||||||
|
resArr.push(route.slice());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let tempVal: number;
|
||||||
|
for (let i = 0, length = nums.length; i < length; i++) {
|
||||||
|
tempVal = nums[i];
|
||||||
|
if (!helperSet.has(tempVal)) {
|
||||||
|
route.push(tempVal);
|
||||||
|
helperSet.add(tempVal);
|
||||||
|
backTracking(nums, route);
|
||||||
|
route.pop();
|
||||||
|
helperSet.delete(tempVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### C
|
### C
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
@ -292,6 +292,34 @@ var permuteUnique = function (nums) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function permuteUnique(nums: number[]): number[][] {
|
||||||
|
nums.sort((a, b) => a - b);
|
||||||
|
const resArr: number[][] = [];
|
||||||
|
const usedArr: boolean[] = new Array(nums.length).fill(false);
|
||||||
|
backTracking(nums, []);
|
||||||
|
return resArr;
|
||||||
|
function backTracking(nums: number[], route: number[]): void {
|
||||||
|
if (route.length === nums.length) {
|
||||||
|
resArr.push(route.slice());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0, length = nums.length; i < length; i++) {
|
||||||
|
if (i > 0 && nums[i] === nums[i - 1] && usedArr[i - 1] === false) continue;
|
||||||
|
if (usedArr[i] === false) {
|
||||||
|
route.push(nums[i]);
|
||||||
|
usedArr[i] = true;
|
||||||
|
backTracking(nums, route);
|
||||||
|
usedArr[i] = false;
|
||||||
|
route.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### Swift
|
### Swift
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
|
@ -457,6 +457,58 @@ var solveNQueens = function(n) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function solveNQueens(n: number): string[][] {
|
||||||
|
const board: string[][] = new Array(n).fill(0).map(_ => new Array(n).fill('.'));
|
||||||
|
const resArr: string[][] = [];
|
||||||
|
backTracking(n, 0, board);
|
||||||
|
return resArr;
|
||||||
|
function backTracking(n: number, rowNum: number, board: string[][]): void {
|
||||||
|
if (rowNum === n) {
|
||||||
|
resArr.push(transformBoard(board));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < n; i++) {
|
||||||
|
if (isValid(i, rowNum, board) === true) {
|
||||||
|
board[rowNum][i] = 'Q';
|
||||||
|
backTracking(n, rowNum + 1, board);
|
||||||
|
board[rowNum][i] = '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function isValid(col: number, row: number, board: string[][]): boolean {
|
||||||
|
const n: number = board.length;
|
||||||
|
if (col < 0 || col >= n || row < 0 || row >= n) return false;
|
||||||
|
// 检查列
|
||||||
|
for (let row of board) {
|
||||||
|
if (row[col] === 'Q') return false;
|
||||||
|
}
|
||||||
|
// 检查45度方向
|
||||||
|
let x: number = col,
|
||||||
|
y: number = row;
|
||||||
|
while (y >= 0 && x < n) {
|
||||||
|
if (board[y--][x++] === 'Q') return false;
|
||||||
|
}
|
||||||
|
// 检查135度方向
|
||||||
|
x = col;
|
||||||
|
y = row;
|
||||||
|
while (x >= 0 && y >= 0) {
|
||||||
|
if (board[y--][x--] === 'Q') return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function transformBoard(board: string[][]): string[] {
|
||||||
|
const resArr = [];
|
||||||
|
for (let row of board) {
|
||||||
|
resArr.push(row.join(''));
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Swift
|
### Swift
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
|
@ -230,6 +230,41 @@ var maxSubArray = function(nums) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
**贪心**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function maxSubArray(nums: number[]): number {
|
||||||
|
let curSum: number = 0;
|
||||||
|
let resMax: number = -Infinity;
|
||||||
|
for (let i = 0, length = nums.length; i < length; i++) {
|
||||||
|
curSum += nums[i];
|
||||||
|
resMax = Math.max(curSum, resMax);
|
||||||
|
if (curSum < 0) curSum = 0;
|
||||||
|
}
|
||||||
|
return resMax;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**动态规划**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 动态规划
|
||||||
|
function maxSubArray(nums: number[]): number {
|
||||||
|
const length = nums.length;
|
||||||
|
if (length === 0) return 0;
|
||||||
|
const dp: number[] = [];
|
||||||
|
dp[0] = nums[0];
|
||||||
|
let resMax: number = nums[0];
|
||||||
|
for (let i = 1; i < length; i++) {
|
||||||
|
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
|
||||||
|
resMax = Math.max(resMax, dp[i]);
|
||||||
|
}
|
||||||
|
return resMax;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -408,6 +408,27 @@ class Solution:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
```
|
```
|
||||||
|
```python
|
||||||
|
# 遵循Carl的写法,只添加了节点判断的部分
|
||||||
|
class Solution:
|
||||||
|
def isValidBST(self, root: TreeNode) -> bool:
|
||||||
|
# method 2
|
||||||
|
que, pre = [], None
|
||||||
|
while root or que:
|
||||||
|
while root:
|
||||||
|
que.append(root)
|
||||||
|
root = root.left
|
||||||
|
root = que.pop()
|
||||||
|
# 对第一个节点只做记录,对后面的节点进行比较
|
||||||
|
if pre is None:
|
||||||
|
pre = root.val
|
||||||
|
else:
|
||||||
|
if pre >= root.val: return False
|
||||||
|
pre = root.val
|
||||||
|
root = root.right
|
||||||
|
return True
|
||||||
|
```
|
||||||
|
|
||||||
## Go
|
## Go
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
|
@ -437,41 +437,6 @@ class Solution:
|
|||||||
return True
|
return True
|
||||||
```
|
```
|
||||||
|
|
||||||
层序遍历
|
|
||||||
|
|
||||||
```python
|
|
||||||
class Solution:
|
|
||||||
def isSymmetric(self, root: TreeNode) -> bool:
|
|
||||||
if not root: return True
|
|
||||||
que, cnt = [[root.left, root.right]], 1
|
|
||||||
while que:
|
|
||||||
nodes, tmp, sign = que.pop(), [], False
|
|
||||||
for node in nodes:
|
|
||||||
if not node:
|
|
||||||
tmp.append(None)
|
|
||||||
tmp.append(None)
|
|
||||||
else:
|
|
||||||
if node.left:
|
|
||||||
tmp.append(node.left)
|
|
||||||
sign = True
|
|
||||||
else:
|
|
||||||
tmp.append(None)
|
|
||||||
if node.right:
|
|
||||||
tmp.append(node.right)
|
|
||||||
sign = True
|
|
||||||
else:
|
|
||||||
tmp.append(None)
|
|
||||||
p1, p2 = 0, len(nodes) - 1
|
|
||||||
while p1 < p2:
|
|
||||||
if (not nodes[p1] and nodes[p2]) or (nodes[p1] and not nodes[p2]): return False
|
|
||||||
elif nodes[p1] and nodes[p2] and nodes[p1].val != nodes[p2].val: return False
|
|
||||||
p1 += 1
|
|
||||||
p2 -= 1
|
|
||||||
if sign: que.append(tmp)
|
|
||||||
cnt += 1
|
|
||||||
return True
|
|
||||||
```
|
|
||||||
|
|
||||||
## Go
|
## Go
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
@ -790,7 +790,7 @@ func findRootIndex(target int,inorder []int) int{
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var buildTree = function(inorder, postorder) {
|
var buildTree = function(inorder, postorder) {
|
||||||
if (!preorder.length) return null;
|
if (!inorder.length) return null;
|
||||||
const rootVal = postorder.pop(); // 从后序遍历的数组中获取中间节点的值, 即数组最后一个值
|
const rootVal = postorder.pop(); // 从后序遍历的数组中获取中间节点的值, 即数组最后一个值
|
||||||
let rootIndex = inorder.indexOf(rootVal); // 获取中间节点在中序遍历中的下标
|
let rootIndex = inorder.indexOf(rootVal); // 获取中间节点在中序遍历中的下标
|
||||||
const root = new TreeNode(rootVal); // 创建中间节点
|
const root = new TreeNode(rootVal); // 创建中间节点
|
||||||
|
@ -355,6 +355,7 @@ func sortedArrayToBST(nums []int) *TreeNode {
|
|||||||
```
|
```
|
||||||
|
|
||||||
## JavaScript
|
## JavaScript
|
||||||
|
递归
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var sortedArrayToBST = function (nums) {
|
var sortedArrayToBST = function (nums) {
|
||||||
@ -372,7 +373,44 @@ var sortedArrayToBST = function (nums) {
|
|||||||
return buildTree(nums, 0, nums.length - 1);
|
return buildTree(nums, 0, nums.length - 1);
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
迭代
|
||||||
|
```JavaScript
|
||||||
|
var sortedArrayToBST = function(nums) {
|
||||||
|
if(nums.length===0){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let root=new TreeNode(0); //初始根节点
|
||||||
|
let nodeQue=[root]; //放遍历的节点,并初始化
|
||||||
|
let leftQue=[0]; //放左区间的下标,初始化
|
||||||
|
let rightQue=[nums.length-1]; // 放右区间的下标
|
||||||
|
|
||||||
|
while(nodeQue.length){
|
||||||
|
let curNode=nodeQue.pop();
|
||||||
|
let left=leftQue.pop();
|
||||||
|
let right=rightQue.pop();
|
||||||
|
let mid=left+Math.floor((right-left)/2);
|
||||||
|
|
||||||
|
curNode.val=nums[mid]; //将下标为mid的元素给中间节点
|
||||||
|
|
||||||
|
// 处理左区间
|
||||||
|
if(left<=mid-1){
|
||||||
|
curNode.left=new TreeNode(0);
|
||||||
|
nodeQue.push(curNode.left);
|
||||||
|
leftQue.push(left);
|
||||||
|
rightQue.push(mid-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理右区间
|
||||||
|
if(right>=mid+1){
|
||||||
|
curNode.right=new TreeNode(0);
|
||||||
|
nodeQue.push(curNode.right);
|
||||||
|
leftQue.push(mid+1);
|
||||||
|
rightQue.push(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
## TypeScript
|
## TypeScript
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
本题首先要清楚两点:
|
本题首先要清楚两点:
|
||||||
|
|
||||||
* 只有一只股票!
|
* 只有一只股票!
|
||||||
* 当前只有买股票或者买股票的操作
|
* 当前只有买股票或者卖股票的操作
|
||||||
|
|
||||||
想获得利润至少要两天为一个交易单元。
|
想获得利润至少要两天为一个交易单元。
|
||||||
|
|
||||||
|
@ -315,5 +315,75 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
C:
|
||||||
|
```C
|
||||||
|
typedef struct HashNodeTag {
|
||||||
|
int key; /* num */
|
||||||
|
struct HashNodeTag *next;
|
||||||
|
}HashNode;
|
||||||
|
|
||||||
|
/* Calcualte the hash key */
|
||||||
|
static inline int hash(int key, int size) {
|
||||||
|
int index = key % size;
|
||||||
|
return (index > 0) ? (index) : (-index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the sum of the squares of its digits*/
|
||||||
|
static inline int calcSquareSum(int num) {
|
||||||
|
unsigned int sum = 0;
|
||||||
|
while(num > 0) {
|
||||||
|
sum += (num % 10) * (num % 10);
|
||||||
|
num = num/10;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define HASH_TABLE_SIZE (32)
|
||||||
|
|
||||||
|
bool isHappy(int n){
|
||||||
|
int sum = n;
|
||||||
|
int index = 0;
|
||||||
|
bool bHappy = false;
|
||||||
|
bool bExit = false;
|
||||||
|
/* allocate the memory for hash table with chaining method*/
|
||||||
|
HashNode ** hashTable = (HashNode **)calloc(HASH_TABLE_SIZE, sizeof(HashNode));
|
||||||
|
|
||||||
|
while(bExit == false) {
|
||||||
|
/* check if n has been calculated */
|
||||||
|
index = hash(n, HASH_TABLE_SIZE);
|
||||||
|
|
||||||
|
HashNode ** p = hashTable + index;
|
||||||
|
|
||||||
|
while((*p) && (bExit == false)) {
|
||||||
|
/* Check if this num was calculated, if yes, this will be endless loop */
|
||||||
|
if((*p)->key == n) {
|
||||||
|
bHappy = false;
|
||||||
|
bExit = true;
|
||||||
|
}
|
||||||
|
/* move to next node of the same index */
|
||||||
|
p = &((*p)->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put n intot hash table */
|
||||||
|
HashNode * newNode = (HashNode *)malloc(sizeof(HashNode));
|
||||||
|
newNode->key = n;
|
||||||
|
newNode->next = NULL;
|
||||||
|
|
||||||
|
*p = newNode;
|
||||||
|
|
||||||
|
sum = calcSquareSum(n);
|
||||||
|
if(sum == 1) {
|
||||||
|
bHappy = true;
|
||||||
|
bExit = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
n = sum;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bHappy;
|
||||||
|
}
|
||||||
|
```
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -275,15 +275,11 @@ func (this *MyQueue) Pop() int {
|
|||||||
|
|
||||||
/** Get the front element. */
|
/** Get the front element. */
|
||||||
func (this *MyQueue) Peek() int {
|
func (this *MyQueue) Peek() int {
|
||||||
for len(this.stack) != 0 {
|
val := this.Pop()
|
||||||
val := this.stack[len(this.stack)-1]
|
if val == 0 {
|
||||||
this.stack = this.stack[:len(this.stack)-1]
|
|
||||||
this.back = append(this.back, val)
|
|
||||||
}
|
|
||||||
if len(this.back) == 0 {
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
val := this.back[len(this.back)-1]
|
this.back = append(this.back, val)
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,6 +506,50 @@ var findItinerary = function(tickets) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function findItinerary(tickets: string[][]): string[] {
|
||||||
|
/**
|
||||||
|
TicketsMap 实例:
|
||||||
|
{ NRT: Map(1) { 'JFK' => 1 }, JFK: Map(2) { 'KUL' => 1, 'NRT' => 1 } }
|
||||||
|
这里选择Map数据结构的原因是:与Object类型的一个主要差异是,Map实例会维护键值对的插入顺序。
|
||||||
|
*/
|
||||||
|
type TicketsMap = {
|
||||||
|
[index: string]: Map<string, number>
|
||||||
|
};
|
||||||
|
tickets.sort((a, b) => {
|
||||||
|
return a[1] < b[1] ? -1 : 1;
|
||||||
|
});
|
||||||
|
const ticketMap: TicketsMap = {};
|
||||||
|
for (const [from, to] of tickets) {
|
||||||
|
if (ticketMap[from] === undefined) {
|
||||||
|
ticketMap[from] = new Map();
|
||||||
|
}
|
||||||
|
ticketMap[from].set(to, (ticketMap[from].get(to) || 0) + 1);
|
||||||
|
}
|
||||||
|
const resRoute = ['JFK'];
|
||||||
|
backTracking(tickets.length, ticketMap, resRoute);
|
||||||
|
return resRoute;
|
||||||
|
function backTracking(ticketNum: number, ticketMap: TicketsMap, route: string[]): boolean {
|
||||||
|
if (route.length === ticketNum + 1) return true;
|
||||||
|
const targetMap = ticketMap[route[route.length - 1]];
|
||||||
|
if (targetMap !== undefined) {
|
||||||
|
for (const [to, count] of targetMap.entries()) {
|
||||||
|
if (count > 0) {
|
||||||
|
route.push(to);
|
||||||
|
targetMap.set(to, count - 1);
|
||||||
|
if (backTracking(ticketNum, ticketMap, route) === true) return true;
|
||||||
|
targetMap.set(to, count);
|
||||||
|
route.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### Swift
|
### Swift
|
||||||
|
|
||||||
直接迭代tickets数组:
|
直接迭代tickets数组:
|
||||||
|
@ -281,6 +281,38 @@ impl Solution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
C:
|
||||||
|
```C
|
||||||
|
int* intersection1(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
|
||||||
|
|
||||||
|
int nums1Cnt[1000] = {0};
|
||||||
|
int lessSize = nums1Size < nums2Size ? nums1Size : nums2Size;
|
||||||
|
int * result = (int *) calloc(lessSize, sizeof(int));
|
||||||
|
int resultIndex = 0;
|
||||||
|
int* tempNums;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Calculate the number's counts for nums1 array */
|
||||||
|
for(i = 0; i < nums1Size; i ++) {
|
||||||
|
nums1Cnt[nums1[i]]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the value in nums2 is existing in nums1 count array */
|
||||||
|
for(i = 0; i < nums2Size; i ++) {
|
||||||
|
if(nums1Cnt[nums2[i]] > 0) {
|
||||||
|
result[resultIndex] = nums2[i];
|
||||||
|
resultIndex ++;
|
||||||
|
/* Clear this count to avoid duplicated value */
|
||||||
|
nums1Cnt[nums2[i]] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
* returnSize = resultIndex;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## 相关题目
|
## 相关题目
|
||||||
|
|
||||||
* 350.两个数组的交集 II
|
* 350.两个数组的交集 II
|
||||||
|
@ -298,5 +298,55 @@ var wiggleMaxLength = function(nums) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
**贪心**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function wiggleMaxLength(nums: number[]): number {
|
||||||
|
let length: number = nums.length;
|
||||||
|
if (length <= 1) return length;
|
||||||
|
let preDiff: number = 0;
|
||||||
|
let curDiff: number = 0;
|
||||||
|
let count: number = 1;
|
||||||
|
for (let i = 1; i < length; i++) {
|
||||||
|
curDiff = nums[i] - nums[i - 1];
|
||||||
|
if (
|
||||||
|
(preDiff <= 0 && curDiff > 0) ||
|
||||||
|
(preDiff >= 0 && curDiff < 0)
|
||||||
|
) {
|
||||||
|
preDiff = curDiff;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**动态规划**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function wiggleMaxLength(nums: number[]): number {
|
||||||
|
const length: number = nums.length;
|
||||||
|
if (length <= 1) return length;
|
||||||
|
const dp: number[][] = new Array(length).fill(0).map(_ => []);
|
||||||
|
dp[0][0] = 1; // 第一个数作为波峰
|
||||||
|
dp[0][1] = 1; // 第一个数作为波谷
|
||||||
|
for (let i = 1; i < length; i++) {
|
||||||
|
dp[i][0] = 1;
|
||||||
|
dp[i][1] = 1;
|
||||||
|
for (let j = 0; j < i; j++) {
|
||||||
|
if (nums[j] < nums[i]) dp[i][0] = Math.max(dp[i][0], dp[j][1] + 1);
|
||||||
|
}
|
||||||
|
for (let j = 0; j < i; j++) {
|
||||||
|
if (nums[j] > nums[i]) dp[i][1] = Math.max(dp[i][1], dp[j][0] + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.max(dp[length - 1][0], dp[length - 1][1]);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -209,7 +209,50 @@ var findContentChildren = function(g, s) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 大饼干尽量喂胃口大的
|
||||||
|
function findContentChildren(g: number[], s: number[]): number {
|
||||||
|
g.sort((a, b) => a - b);
|
||||||
|
s.sort((a, b) => a - b);
|
||||||
|
const childLength: number = g.length,
|
||||||
|
cookieLength: number = s.length;
|
||||||
|
let curChild: number = childLength - 1,
|
||||||
|
curCookie: number = cookieLength - 1;
|
||||||
|
let resCount: number = 0;
|
||||||
|
while (curChild >= 0 && curCookie >= 0) {
|
||||||
|
if (g[curChild] <= s[curCookie]) {
|
||||||
|
curCookie--;
|
||||||
|
resCount++;
|
||||||
|
}
|
||||||
|
curChild--;
|
||||||
|
}
|
||||||
|
return resCount;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 小饼干先喂饱小胃口的
|
||||||
|
function findContentChildren(g: number[], s: number[]): number {
|
||||||
|
g.sort((a, b) => a - b);
|
||||||
|
s.sort((a, b) => a - b);
|
||||||
|
const childLength: number = g.length,
|
||||||
|
cookieLength: number = s.length;
|
||||||
|
let curChild: number = 0,
|
||||||
|
curCookie: number = 0;
|
||||||
|
while (curChild < childLength && curCookie < cookieLength) {
|
||||||
|
if (g[curChild] <= s[curCookie]) {
|
||||||
|
curChild++;
|
||||||
|
}
|
||||||
|
curCookie++;
|
||||||
|
}
|
||||||
|
return curChild;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### C
|
### C
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int cmp(int* a, int* b) {
|
int cmp(int* a, int* b) {
|
||||||
return *a - *b;
|
return *a - *b;
|
||||||
|
@ -396,7 +396,35 @@ var findSubsequences = function(nums) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function findSubsequences(nums: number[]): number[][] {
|
||||||
|
const resArr: number[][] = [];
|
||||||
|
backTracking(nums, 0, []);
|
||||||
|
return resArr;
|
||||||
|
function backTracking(nums: number[], startIndex: number, route: number[]): void {
|
||||||
|
let length: number = nums.length;
|
||||||
|
if (route.length >= 2) {
|
||||||
|
resArr.push(route.slice());
|
||||||
|
}
|
||||||
|
const usedSet: Set<number> = new Set();
|
||||||
|
for (let i = startIndex; i < length; i++) {
|
||||||
|
if (
|
||||||
|
nums[i] < route[route.length - 1] ||
|
||||||
|
usedSet.has(nums[i])
|
||||||
|
) continue;
|
||||||
|
usedSet.add(nums[i]);
|
||||||
|
route.push(nums[i]);
|
||||||
|
backTracking(nums, i + 1, route);
|
||||||
|
route.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### C
|
### C
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int* path;
|
int* path;
|
||||||
int pathTop;
|
int pathTop;
|
||||||
|
@ -276,7 +276,7 @@ func search(nums []int, target int) int {
|
|||||||
```
|
```
|
||||||
|
|
||||||
**JavaScript:**
|
**JavaScript:**
|
||||||
(版本一)左闭右闭区间
|
(版本一)左闭右闭区间 [left, right]
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
@ -285,10 +285,12 @@ func search(nums []int, target int) int {
|
|||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
var search = function(nums, target) {
|
var search = function(nums, target) {
|
||||||
|
// right是数组最后一个数的下标,num[right]在查找范围内,是左闭右闭区间
|
||||||
let left = 0, right = nums.length - 1;
|
let left = 0, right = nums.length - 1;
|
||||||
// 使用左闭右闭区间
|
// 当left=right时,由于nums[right]在查找范围内,所以要包括此情况
|
||||||
while (left <= right) {
|
while (left <= right) {
|
||||||
let mid = left + Math.floor((right - left)/2);
|
let mid = left + Math.floor((right - left)/2);
|
||||||
|
// 如果中间数大于目标值,要把中间数排除查找范围,所以右边界更新为mid-1;如果右边界更新为mid,那中间数还在下次查找范围内
|
||||||
if (nums[mid] > target) {
|
if (nums[mid] > target) {
|
||||||
right = mid - 1; // 去左面闭区间寻找
|
right = mid - 1; // 去左面闭区间寻找
|
||||||
} else if (nums[mid] < target) {
|
} else if (nums[mid] < target) {
|
||||||
@ -300,7 +302,7 @@ var search = function(nums, target) {
|
|||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
(版本二)左闭右开区间
|
(版本二)左闭右开区间 [left, right)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/**
|
/**
|
||||||
@ -309,10 +311,13 @@ var search = function(nums, target) {
|
|||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
var search = function(nums, target) {
|
var search = function(nums, target) {
|
||||||
|
// right是数组最后一个数的下标+1,nums[right]不在查找范围内,是左闭右开区间
|
||||||
let left = 0, right = nums.length;
|
let left = 0, right = nums.length;
|
||||||
// 使用左闭右开区间 [left, right)
|
// 当left=right时,由于nums[right]不在查找范围,所以不必包括此情况
|
||||||
while (left < right) {
|
while (left < right) {
|
||||||
let mid = left + Math.floor((right - left)/2);
|
let mid = left + Math.floor((right - left)/2);
|
||||||
|
// 如果中间值大于目标值,中间值不应在下次查找的范围内,但中间值的前一个值应在;
|
||||||
|
// 由于right本来就不在查找范围内,所以将右边界更新为中间值,如果更新右边界为mid-1则将中间值的前一个值也踢出了下次寻找范围
|
||||||
if (nums[mid] > target) {
|
if (nums[mid] > target) {
|
||||||
right = mid; // 去左区间寻找
|
right = mid; // 去左区间寻找
|
||||||
} else if (nums[mid] < target) {
|
} else if (nums[mid] < target) {
|
||||||
|
@ -220,6 +220,73 @@ int main() {
|
|||||||
## Go
|
## Go
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type TreeNode struct {
|
||||||
|
Val int
|
||||||
|
Left *TreeNode
|
||||||
|
Right *TreeNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func constructBinaryTree(array []int) *TreeNode {
|
||||||
|
var root *TreeNode
|
||||||
|
nodes := make([]*TreeNode, len(array))
|
||||||
|
|
||||||
|
// 初始化二叉树节点
|
||||||
|
for i := 0; i < len(nodes); i++ {
|
||||||
|
var node *TreeNode
|
||||||
|
if array[i] != -1 {
|
||||||
|
node = &TreeNode{Val: array[i]}
|
||||||
|
}
|
||||||
|
nodes[i] = node
|
||||||
|
if i == 0 {
|
||||||
|
root = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 串联节点
|
||||||
|
for i := 0; i*2+2 < len(array); i++ {
|
||||||
|
if nodes[i] != nil {
|
||||||
|
nodes[i].Left = nodes[i*2+1]
|
||||||
|
nodes[i].Right = nodes[i*2+2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
func printBinaryTree(root *TreeNode, n int) {
|
||||||
|
var queue []*TreeNode
|
||||||
|
if root != nil {
|
||||||
|
queue = append(queue, root)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := []int{}
|
||||||
|
for len(queue) > 0 {
|
||||||
|
for j := 0; j < len(queue); j++ {
|
||||||
|
node := queue[j]
|
||||||
|
if node != nil {
|
||||||
|
result = append(result, node.Val)
|
||||||
|
queue = append(queue, node.Left)
|
||||||
|
queue = append(queue, node.Right)
|
||||||
|
} else {
|
||||||
|
result = append(result, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 清除队列中的本层节点, 进入下一层遍历
|
||||||
|
queue = queue[len(queue):]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数n控制输出值数量, 否则二叉树最后一层叶子节点的孩子节点也会被打印(但是这些孩子节点是不存在的).
|
||||||
|
fmt.Println(result[:n])
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
array := []int{4, 1, 6, 0, 2, 5, 7, -1, -1, -1, 3, -1, -1, -1, 8}
|
||||||
|
root := constructBinaryTree(array)
|
||||||
|
printBinaryTree(root, len(array))
|
||||||
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## JavaScript
|
## JavaScript
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
* 空间复杂度:$O(n)$,递归深度为n,所以系统栈所用空间为$O(n)$,每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为$O(n)$。
|
* 空间复杂度:$O(n)$,递归深度为n,所以系统栈所用空间为$O(n)$,每一层递归所用的空间都是常数级别,注意代码里的result和path都是全局变量,就算是放在参数里,传的也是引用,并不会新申请内存空间,最终空间复杂度为$O(n)$。
|
||||||
|
|
||||||
排列问题分析:
|
排列问题分析:
|
||||||
* 时间复杂度:$O(n!)$,这个可以从排列的树形图中很明显发现,每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!。
|
* 时间复杂度:$O(n!)$,这个可以从排列的树形图中很明显发现,每一层节点为n,第二层每一个分支都延伸了n-1个分支,再往下又是n-2个分支,所以一直到叶子节点一共就是 n * n-1 * n-2 * ..... 1 = n!。每个叶子节点都会有一个构造全排列填进数组的操作(对应的代码:`result.push_back(path)`),该操作的复杂度为$O(n)$。所以,最终时间复杂度为:n * n!,简化为$O(n!)$。
|
||||||
* 空间复杂度:$O(n)$,和子集问题同理。
|
* 空间复杂度:$O(n)$,和子集问题同理。
|
||||||
|
|
||||||
组合问题分析:
|
组合问题分析:
|
||||||
|
@ -365,6 +365,87 @@ class Solution:
|
|||||||
return res
|
return res
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
**90.子集II**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function subsetsWithDup(nums: number[]): number[][] {
|
||||||
|
nums.sort((a, b) => a - b);
|
||||||
|
const resArr: number[][] = [];
|
||||||
|
backTraking(nums, 0, []);
|
||||||
|
return resArr;
|
||||||
|
function backTraking(nums: number[], startIndex: number, route: number[]): void {
|
||||||
|
resArr.push(route.slice());
|
||||||
|
const helperSet: Set<number> = 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**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function combinationSum2(candidates: number[], target: number): number[][] {
|
||||||
|
candidates.sort((a, b) => a - b);
|
||||||
|
const resArr: number[][] = [];
|
||||||
|
backTracking(candidates, target, 0, 0, []);
|
||||||
|
return resArr;
|
||||||
|
function backTracking(
|
||||||
|
candidates: number[], target: number,
|
||||||
|
curSum: number, startIndex: number, route: number[]
|
||||||
|
) {
|
||||||
|
if (curSum > target) return;
|
||||||
|
if (curSum === target) {
|
||||||
|
resArr.push(route.slice());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const helperSet: Set<number> = new Set();
|
||||||
|
for (let i = startIndex, length = candidates.length; i < length; i++) {
|
||||||
|
let tempVal: number = 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**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function permuteUnique(nums: number[]): number[][] {
|
||||||
|
const resArr: number[][] = [];
|
||||||
|
const usedArr: boolean[] = [];
|
||||||
|
backTracking(nums, []);
|
||||||
|
return resArr;
|
||||||
|
function backTracking(nums: number[], route: number[]): void {
|
||||||
|
if (nums.length === route.length) {
|
||||||
|
resArr.push(route.slice());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const usedSet: Set<number> = 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user