diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index e041937f..813e9b02 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -181,7 +181,71 @@ var removeNthFromEnd = function(head, n) { return ret.next; }; ``` +TypeScript: + +版本一(快慢指针法): + +```typescript +function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { + let newHead: ListNode | null = new ListNode(0, head); + let slowNode: ListNode | null = newHead, + fastNode: ListNode | null = newHead; + for (let i = 0; i < n; i++) { + fastNode = fastNode.next; + } + while (fastNode.next) { + fastNode = fastNode.next; + slowNode = slowNode.next; + } + slowNode.next = slowNode.next.next; + return newHead.next; +}; +``` + +版本二(计算节点总数法): + +```typescript +function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { + let curNode: ListNode | null = head; + let listSize: number = 0; + while (curNode) { + curNode = curNode.next; + listSize++; + } + if (listSize === n) { + head = head.next; + } else { + curNode = head; + for (let i = 0; i < listSize - n - 1; i++) { + curNode = curNode.next; + } + curNode.next = curNode.next.next; + } + return head; +}; +``` + +版本三(递归倒退n法): + +```typescript +function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { + let newHead: ListNode | null = new ListNode(0, head); + let cnt = 0; + function recur(node) { + if (node === null) return; + recur(node.next); + cnt++; + if (cnt === n + 1) { + node.next = node.next.next; + } + } + recur(newHead); + return newHead.next; +}; +``` + Kotlin: + ```Kotlin fun removeNthFromEnd(head: ListNode?, n: Int): ListNode? { val pre = ListNode(0).apply { diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 01abc7b4..bf1fd5e1 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -250,6 +250,38 @@ var swapPairs = function (head) { }; ``` +TypeScript: + +```typescript +function swapPairs(head: ListNode | null): ListNode | null { + /** + * 初始状态: + * curNode -> node1 -> node2 -> tmepNode + * 转换过程: + * curNode -> node2 + * curNode -> node2 -> node1 + * curNode -> node2 -> node1 -> tempNode + * curNode = node1 + */ + let retNode: ListNode | null = new ListNode(0, head), + curNode: ListNode | null = retNode, + node1: ListNode | null = null, + node2: ListNode | null = null, + tempNode: ListNode | null = null; + + while (curNode && curNode.next && curNode.next.next) { + node1 = curNode.next; + node2 = curNode.next.next; + tempNode = node2.next; + curNode.next = node2; + node2.next = node1; + node1.next = tempNode; + curNode = node1; + } + return retNode.next; +}; +``` + Kotlin: ```kotlin diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md index 2b96e41b..dfd90b82 100644 --- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md +++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md @@ -389,6 +389,51 @@ class Solution: ### Go ```go +func searchRange(nums []int, target int) []int { + leftBorder := getLeft(nums, target) + rightBorder := getRight(nums, target) + // 情况一 + if leftBorder == -2 || rightBorder == -2 { + return []int{-1, -1} + } + // 情况三 + if rightBorder - leftBorder > 1 { + return []int{leftBorder + 1, rightBorder - 1} + } + // 情况二 + return []int{-1, -1} +} + +func getLeft(nums []int, target int) int { + left, right := 0, len(nums)-1 + border := -2 // 记录border没有被赋值的情况;这里不能赋值-1,target = num[0]时,会无法区分情况一和情况二 + for left <= right { // []闭区间 + mid := left + ((right - left) >> 1) + if nums[mid] >= target { // 找到第一个等于target的位置 + right = mid - 1 + border = right + } else { + left = mid + 1 + } + } + return border +} + +func getRight(nums []int, target int) int { + left, right := 0, len(nums) - 1 + border := -2 + for left <= right { + mid := left + ((right - left) >> 1) + if nums[mid] > target { + right = mid - 1 + } else { // 找到第一个大于target的位置 + left = mid + 1 + border = left + } + } + return border + +} ``` ### JavaScript diff --git a/problems/0059.螺旋矩阵II.md b/problems/0059.螺旋矩阵II.md index c7e91b4d..3f7a59ca 100644 --- a/problems/0059.螺旋矩阵II.md +++ b/problems/0059.螺旋矩阵II.md @@ -287,6 +287,51 @@ var generateMatrix = function(n) { ``` +TypeScript: + +```typescript +function generateMatrix(n: number): number[][] { + let loopNum: number = Math.floor(n / 2); + const resArr: number[][] = new Array(n).fill(1).map(i => new Array(n)); + let chunkNum: number = n - 1; + let startX: number = 0; + let startY: number = 0; + let value: number = 1; + let x: number, y: number; + while (loopNum--) { + x = startX; + y = startY; + while (x < startX + chunkNum) { + resArr[y][x] = value; + x++; + value++; + } + while (y < startY + chunkNum) { + resArr[y][x] = value; + y++; + value++; + } + while (x > startX) { + resArr[y][x] = value; + x--; + value++; + } + while (y > startY) { + resArr[y][x] = value; + y--; + value++; + } + startX++; + startY++; + chunkNum -= 2; + } + if (n % 2 === 1) { + resArr[startX][startY] = value; + } + return resArr; +}; +``` + Go: ```go diff --git a/problems/0062.不同路径.md b/problems/0062.不同路径.md index e209abb1..efa85a03 100644 --- a/problems/0062.不同路径.md +++ b/problems/0062.不同路径.md @@ -347,6 +347,42 @@ var uniquePaths = function(m, n) { }; ``` +### C +```c +//初始化dp数组 +int **initDP(int m, int n) { + //动态开辟dp数组 + int **dp = (int**)malloc(sizeof(int *) * m); + int i, j; + for(i = 0; i < m; ++i) { + dp[i] = (int *)malloc(sizeof(int) * n); + } + + //从0,0到i,0只有一种走法,所以dp[i][0]都是1,同理dp[0][j]也是1 + for(i = 0; i < m; ++i) + dp[i][0] = 1; + for(j = 0; j < n; ++j) + dp[0][j] = 1; + return dp; +} + +int uniquePaths(int m, int n){ + //dp数组,dp[i][j]代表从dp[0][0]到dp[i][j]有几种走法 + int **dp = initDP(m, n); + + int i, j; + //到达dp[i][j]只能从dp[i-1][j]和dp[i][j-1]出发 + //dp[i][j] = dp[i-1][j] + dp[i][j-1] + for(i = 1; i < m; ++i) { + for(j = 1; j < n; ++j) { + dp[i][j] = dp[i-1][j] + dp[i][j-1]; + } + } + int result = dp[m-1][n-1]; + free(dp); + return result; +} +``` -----------------------
diff --git a/problems/0063.不同路径II.md b/problems/0063.不同路径II.md index 490b6b5c..6f405d6a 100644 --- a/problems/0063.不同路径II.md +++ b/problems/0063.不同路径II.md @@ -333,6 +333,60 @@ var uniquePathsWithObstacles = function(obstacleGrid) { }; ``` +C +```c +//初始化dp数组 +int **initDP(int m, int n, int** obstacleGrid) { + int **dp = (int**)malloc(sizeof(int*) * m); + int i, j; + //初始化每一行数组 + for(i = 0; i < m; ++i) { + dp[i] = (int*)malloc(sizeof(int) * n); + } + + //先将第一行第一列设为0 + for(i = 0; i < m; ++i) { + dp[i][0] = 0; + } + for(j = 0; j < n; ++j) { + dp[0][j] = 0; + } + + //若碰到障碍,之后的都走不了。退出循环 + for(i = 0; i < m; ++i) { + if(obstacleGrid[i][0]) { + break; + } + dp[i][0] = 1; + } + for(j = 0; j < n; ++j) { + if(obstacleGrid[0][j]) + break; + dp[0][j] = 1; + } + return dp; +} + +int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){ + int m = obstacleGridSize, n = *obstacleGridColSize; + //初始化dp数组 + int **dp = initDP(m, n, obstacleGrid); + + int i, j; + for(i = 1; i < m; ++i) { + for(j = 1; j < n; ++j) { + //若当前i,j位置有障碍 + if(obstacleGrid[i][j]) + //路线不同 + dp[i][j] = 0; + else + dp[i][j] = dp[i-1][j] + dp[i][j-1]; + } + } + //返回最后终点的路径个数 + return dp[m-1][n-1]; +} +``` -----------------------
diff --git a/problems/0070.爬楼梯.md b/problems/0070.爬楼梯.md index 97db670a..7f47a991 100644 --- a/problems/0070.爬楼梯.md +++ b/problems/0070.爬楼梯.md @@ -296,6 +296,48 @@ var climbStairs = function(n) { }; ``` +### C +```c +int climbStairs(int n){ + //若n<=2,返回n + if(n <= 2) + return n; + //初始化dp数组,数组大小为n+1 + int *dp = (int *)malloc(sizeof(int) * (n + 1)); + dp[0] = 0, dp[1] = 1, dp[2] = 2; + + //从前向后遍历数组,dp[i] = dp[i-1] + dp[i-2] + int i; + for(i = 3; i <= n; ++i) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + //返回dp[n] + return dp[n]; +} +``` + +优化空间复杂度: +```c +int climbStairs(int n){ + //若n<=2,返回n + if(n <= 2) + return n; + //初始化dp数组,数组大小为3 + int *dp = (int *)malloc(sizeof(int) * 3); + dp[1] = 1, dp[2] = 2; + + //只记录前面两个台阶的状态 + int i; + for(i = 3; i <= n; ++i) { + int sum = dp[1] + dp[2]; + dp[1] = dp[2]; + dp[2] = sum; + } + //返回dp[2] + return dp[2]; +} +``` + -----------------------
diff --git a/problems/0142.环形链表II.md b/problems/0142.环形链表II.md index dfe042b8..e8ca950d 100644 --- a/problems/0142.环形链表II.md +++ b/problems/0142.环形链表II.md @@ -294,7 +294,30 @@ var detectCycle = function(head) { }; ``` +TypeScript: + +```typescript +function detectCycle(head: ListNode | null): ListNode | null { + let slowNode: ListNode | null = head, + fastNode: ListNode | null = head; + while (fastNode !== null && fastNode.next !== null) { + slowNode = (slowNode as ListNode).next; + fastNode = fastNode.next.next; + if (slowNode === fastNode) { + slowNode = head; + while (slowNode !== fastNode) { + slowNode = (slowNode as ListNode).next; + fastNode = (fastNode as ListNode).next; + } + return slowNode; + } + } + return null; +}; +``` + Swift: + ```swift class Solution { func detectCycle(_ head: ListNode?) -> ListNode? { diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md index 2d678151..f0a46a40 100644 --- a/problems/0202.快乐数.md +++ b/problems/0202.快乐数.md @@ -232,7 +232,27 @@ var isHappy = function(n) { }; ``` +TypeScript: + +```typescript +function isHappy(n: number): boolean { + // Utils + // 计算val各位的平方和 + function calcSum(val: number): number { + return String(val).split("").reduce((pre, cur) => (pre + Number(cur) * Number(cur)), 0); + } + + let storeSet: Set = new Set(); + while (n !== 1 && !storeSet.has(n)) { + storeSet.add(n); + n = calcSum(n); + } + return n === 1; +}; +``` + Swift: + ```swift // number 每个位置上的数字的平方和 func getSum(_ number: Int) -> Int { diff --git a/problems/0242.有效的字母异位词.md b/problems/0242.有效的字母异位词.md index cdcf39ce..52f8e667 100644 --- a/problems/0242.有效的字母异位词.md +++ b/problems/0242.有效的字母异位词.md @@ -214,7 +214,23 @@ var isAnagram = function(s, t) { }; ``` +TypeScript: + +```typescript +function isAnagram(s: string, t: string): boolean { + if (s.length !== t.length) return false; + let helperArr: number[] = new Array(26).fill(0); + let pivot: number = 'a'.charCodeAt(0); + for (let i = 0, length = s.length; i < length; i++) { + helperArr[s.charCodeAt(i) - pivot]++; + helperArr[t.charCodeAt(i) - pivot]--; + } + return helperArr.every(i => i === 0); +}; +``` + Swift: + ```Swift func isAnagram(_ s: String, _ t: String) -> Bool { if s.count != t.count { diff --git a/problems/0283.移动零.md b/problems/0283.移动零.md index 13b9c26c..bb75a696 100644 --- a/problems/0283.移动零.md +++ b/problems/0283.移动零.md @@ -89,9 +89,33 @@ Python: for i in range(slow, len(nums)): nums[i] = 0 ``` +交换前后变量,避免补零 +```python + def moveZeroes(self, nums: List[int]) -> None: + slow, fast = 0, 0 + while fast < len(nums): + if nums[fast] != 0: + nums[slow], nums[fast] = nums[fast], nums[slow] + slow += 1 # 保持[0, slow)区间是没有0的 + fast += 1 +``` Go: +```go +func moveZeroes(nums []int) { + slow := 0 + for fast := 0; fast < len(nums); fast ++ { + if nums[fast] != 0 { + temp := nums[slow] + nums[slow] = nums[fast] + nums[fast] = temp + slow++ + } + } +} +``` + JavaScript: ```javascript var moveZeroes = function(nums) { diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 812c4489..92342f17 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -190,7 +190,33 @@ var intersection = function(nums1, nums2) { }; ``` +TypeScript: + +版本一(正常解法): + +```typescript +function intersection(nums1: number[], nums2: number[]): number[] { + let resSet: Set = new Set(), + nums1Set: Set = new Set(nums1); + for (let i of nums2) { + if (nums1Set.has(i)) { + resSet.add(i); + } + } + return Array.from(resSet); +}; +``` + +版本二(秀操作): + +```typescript +function intersection(nums1: number[], nums2: number[]): number[] { + return Array.from(new Set(nums1.filter(i => nums2.includes(i)))) +}; +``` + Swift: + ```swift func intersection(_ nums1: [Int], _ nums2: [Int]) -> [Int] { var set1 = Set() diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md index ebfe648f..33bbad55 100644 --- a/problems/0452.用最少数量的箭引爆气球.md +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -239,5 +239,30 @@ int findMinArrowShots(int** points, int pointsSize, int* pointsColSize){ } ``` +### Rust +```Rust +use std::cmp; +impl Solution { + pub fn find_min_arrow_shots(mut points: Vec>) -> i32 { + if points.is_empty() { + return 0; + } + points.sort_by_key(|point| point[0]); + + let size = points.len(); + let mut count = 1; + + for i in 1..size { + if points[i][0] > points[i-1][1] { + count += 1; + } else { + points[i][1] = cmp::min(points[i][1], points[i-1][1]); + } + } + + return count; + } +} +``` -----------------------
diff --git a/problems/0509.斐波那契数.md b/problems/0509.斐波那契数.md index d8020d83..c6ce76c0 100644 --- a/problems/0509.斐波那契数.md +++ b/problems/0509.斐波那契数.md @@ -245,6 +245,38 @@ var fib = function(n) { }; ``` +### C +动态规划: +```c +int fib(int n){ + //当n <= 1时,返回n + if(n <= 1) + return n; + //动态开辟一个int数组,大小为n+1 + int *dp = (int *)malloc(sizeof(int) * (n + 1)); + //设置0号位为0,1号为为1 + dp[0] = 0; + dp[1] = 1; + + //从前向后遍历数组(i=2; i <= n; ++i),下标为n时的元素为dp[i-1] + dp[i-2] + int i; + for(i = 2; i <= n; ++i) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; +} +``` + +递归实现: +```c +int fib(int n){ + //若n小于等于1,返回n + if(n <= 1) + return n; + //否则返回fib(n-1) + fib(n-2) + return fib(n-1) + fib(n-2); +} +``` ----------------------- diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md index 0009f06c..e94e4d24 100644 --- a/problems/0746.使用最小花费爬楼梯.md +++ b/problems/0746.使用最小花费爬楼梯.md @@ -266,5 +266,21 @@ var minCostClimbingStairs = function(cost) { }; ``` +### C +```c +int minCostClimbingStairs(int* cost, int costSize){ + //开辟dp数组,大小为costSize + int *dp = (int *)malloc(sizeof(int) * costSize); + //初始化dp[0] = cost[0], dp[1] = cost[1] + dp[0] = cost[0], dp[1] = cost[1]; + + int i; + for(i = 2; i < costSize; ++i) { + dp[i] = (dp[i-1] < dp[i-2] ? dp[i-1] : dp[i-2]) + cost[i]; + } + //选出倒数2层楼梯中较小的 + return dp[i-1] < dp[i-2] ? dp[i-1] : dp[i-2]; +} +``` -----------------------
diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index e8198aa0..dd91f069 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -239,6 +239,43 @@ var getIntersectionNode = function(headA, headB) { }; ``` +TypeScript: + +```typescript +function getIntersectionNode(headA: ListNode | null, headB: ListNode | null): ListNode | null { + let sizeA: number = 0, + sizeB: number = 0; + let curA: ListNode | null = headA, + curB: ListNode | null = headB; + while (curA) { + sizeA++; + curA = curA.next; + } + while (curB) { + sizeB++; + curB = curB.next; + } + curA = headA; + curB = headB; + if (sizeA < sizeB) { + [sizeA, sizeB] = [sizeB, sizeA]; + [curA, curB] = [curB, curA]; + } + let gap = sizeA - sizeB; + while (gap-- && curA) { + curA = curA.next; + } + while (curA && curB) { + if (curA === curB) { + return curA; + } + curA = curA.next; + curB = curB.next; + } + return null; +}; +``` + C: ```c