diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md
index e6dc82dd..4f1d711a 100644
--- a/problems/0015.三数之和.md
+++ b/problems/0015.三数之和.md
@@ -345,6 +345,76 @@ var threeSum = function(nums) {
return res
};
```
+
+解法二:nSum通用解法。递归
+
+```js
+/**
+ * nsum通用解法,支持2sum,3sum,4sum...等等
+ * 时间复杂度分析:
+ * 1. n = 2时,时间复杂度O(NlogN),排序所消耗的时间。、
+ * 2. n > 2时,时间复杂度为O(N^n-1),即N的n-1次方,至少是2次方,此时可省略排序所消耗的时间。举例:3sum为O(n^2),4sum为O(n^3)
+ * @param {number[]} nums
+ * @return {number[][]}
+ */
+var threeSum = function (nums) {
+ // nsum通用解法核心方法
+ function nSumTarget(nums, n, start, target) {
+ // 前提:nums要先排序好
+ let res = [];
+ if (n === 2) {
+ res = towSumTarget(nums, start, target);
+ } else {
+ for (let i = start; i < nums.length; i++) {
+ // 递归求(n - 1)sum
+ let subRes = nSumTarget(
+ nums,
+ n - 1,
+ i + 1,
+ target - nums[i]
+ );
+ for (let j = 0; j < subRes.length; j++) {
+ res.push([nums[i], ...subRes[j]]);
+ }
+ // 跳过相同元素
+ while (nums[i] === nums[i + 1]) i++;
+ }
+ }
+ return res;
+ }
+
+ function towSumTarget(nums, start, target) {
+ // 前提:nums要先排序好
+ let res = [];
+ let len = nums.length;
+ let left = start;
+ let right = len - 1;
+ while (left < right) {
+ let sum = nums[left] + nums[right];
+ if (sum < target) {
+ while (nums[left] === nums[left + 1]) left++;
+ left++;
+ } else if (sum > target) {
+ while (nums[right] === nums[right - 1]) right--;
+ right--;
+ } else {
+ // 相等
+ res.push([nums[left], nums[right]]);
+ // 跳过相同元素
+ while (nums[left] === nums[left + 1]) left++;
+ while (nums[right] === nums[right - 1]) right--;
+ left++;
+ right--;
+ }
+ }
+ return res;
+ }
+ nums.sort((a, b) => a - b);
+ // n = 3,此时求3sum之和
+ return nSumTarget(nums, 3, 0, 0);
+};
+```
+
TypeScript:
```typescript
diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md
index b44d21ed..c3ff9d53 100644
--- a/problems/0020.有效的括号.md
+++ b/problems/0020.有效的括号.md
@@ -400,6 +400,37 @@ bool isValid(char * s){
return !stackTop;
}
```
+
+
+PHP:
+```php
+// https://www.php.net/manual/zh/class.splstack.php
+class Solution
+{
+ function isValid($s){
+ $stack = new SplStack();
+ for ($i = 0; $i < strlen($s); $i++) {
+ if ($s[$i] == "(") {
+ $stack->push(')');
+ } else if ($s[$i] == "{") {
+ $stack->push('}');
+ } else if ($s[$i] == "[") {
+ $stack->push(']');
+ // 2、遍历匹配过程中,发现栈内没有要匹配的字符 return false
+ // 3、遍历匹配过程中,栈已为空,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
+ } else if ($stack->isEmpty() || $stack->top() != $s[$i]) {
+ return false;
+ } else {//$stack->top() == $s[$i]
+ $stack->pop();
+ }
+ }
+ // 1、遍历完,但是栈不为空,说明有相应的括号没有被匹配,return false
+ return $stack->isEmpty();
+ }
+}
+```
+
+
Scala:
```scala
object Solution {
@@ -422,5 +453,6 @@ object Solution {
}
}
```
+
-----------------------
diff --git a/problems/0189.旋转数组.md b/problems/0189.旋转数组.md
index 3ffed877..23092f9c 100644
--- a/problems/0189.旋转数组.md
+++ b/problems/0189.旋转数组.md
@@ -7,6 +7,8 @@
# 189. 旋转数组
+[力扣题目链接](https://leetcode.cn/problems/rotate-array/)
+
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
进阶:
@@ -160,6 +162,27 @@ var rotate = function (nums, k) {
};
```
+## TypeScript
+
+```typescript
+function rotate(nums: number[], k: number): void {
+ const length: number = nums.length;
+ k %= length;
+ reverseByRange(nums, 0, length - 1);
+ reverseByRange(nums, 0, k - 1);
+ reverseByRange(nums, k, length - 1);
+};
+function reverseByRange(nums: number[], left: number, right: number): void {
+ while (left < right) {
+ const temp = nums[left];
+ nums[left] = nums[right];
+ nums[right] = temp;
+ left++;
+ right--;
+ }
+}
+```
+
-----------------------
diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md
index 994d1875..40415d8d 100644
--- a/problems/0225.用队列实现栈.md
+++ b/problems/0225.用队列实现栈.md
@@ -816,7 +816,6 @@ class MyStack {
}
```
Scala:
-
使用两个队列模拟栈:
```scala
import scala.collection.mutable
@@ -897,6 +896,86 @@ class MyStack() {
def empty(): Boolean = {
queue.isEmpty
}
+ }
+```
+
+
+PHP
+> 双对列
+```php
+// SplQueue 类通过使用一个双向链表来提供队列的主要功能。(PHP 5 >= 5.3.0, PHP 7, PHP 8)
+// https://www.php.net/manual/zh/class.splqueue.php
+class MyStack {
+ public $queueMain; // 保存数据
+ public $queueTmp; // 辅助作用
+
+ function __construct() {
+ $this->queueMain=new SplQueue();
+ $this->queueTmp=new SplQueue();
+ }
+
+ // queueMain: 1,2,3 <= add
+ function push($x) {
+ $this->queueMain->enqueue($x);
+ }
+
+ function pop() {
+ $qmSize = $this->queueMain->Count();
+ $qmSize --;
+ // queueMain: 3,2,1 => pop =>2,1 => add => 2,1 :queueTmp
+ while($qmSize --){
+ $this->queueTmp->enqueue($this->queueMain->dequeue());
+ }
+ // queueMain: 3
+ $val = $this->queueMain->dequeue();
+ // queueMain <= queueTmp
+ $this->queueMain = $this->queueTmp;
+ // 清空queueTmp,下次使用
+ $this->queueTmp = new SplQueue();
+ return $val;
+ }
+
+ function top() {
+ // 底层是双链表实现:从双链表的末尾查看节点
+ return $this->queueMain->top();
+ }
+
+ function empty() {
+ return $this->queueMain->isEmpty();
+ }
+}
+```
+> 单对列
+```php
+class MyStack {
+ public $queue;
+
+ function __construct() {
+ $this->queue=new SplQueue();
+ }
+
+ function push($x) {
+ $this->queue->enqueue($x);
+ }
+
+ function pop() {
+ $qmSize = $this->queue->Count();
+ $qmSize --;
+ //queue: 3,2,1 => pop =>2,1 => add => 2,1,3 :queue
+ while($qmSize --){
+ $this->queue->enqueue($this->queue->dequeue());
+ }
+ $val = $this->queue->dequeue();
+ return $val;
+ }
+
+ function top() {
+ return $this->queue->top();
+ }
+
+ function empty() {
+ return $this->queue->isEmpty();
+ }
}
```
-----------------------
diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md
index 47993fa1..4662e2f2 100644
--- a/problems/0232.用栈实现队列.md
+++ b/problems/0232.用栈实现队列.md
@@ -495,6 +495,53 @@ void myQueueFree(MyQueue* obj) {
obj->stackOutTop = 0;
}
```
+
+
+PHP:
+```php
+// SplStack 类通过使用一个双向链表来提供栈的主要功能。[PHP 5 >= 5.3.0, PHP 7, PHP 8]
+// https://www.php.net/manual/zh/class.splstack.php
+class MyQueue {
+ // 双栈模拟队列:In栈存储数据;Out栈辅助处理
+ private $stackIn;
+ private $stackOut;
+
+ function __construct() {
+ $this->stackIn = new SplStack();
+ $this->stackOut = new SplStack();
+ }
+
+ // In: 1 2 3 <= push
+ function push($x) {
+ $this->stackIn->push($x);
+ }
+
+ function pop() {
+ $this->peek();
+ return $this->stackOut->pop();
+ }
+
+ function peek() {
+ if($this->stackOut->isEmpty()){
+ $this->shift();
+ }
+ return $this->stackOut->top();
+ }
+
+ function empty() {
+ return $this->stackOut->isEmpty() && $this->stackIn->isEmpty();
+ }
+
+ // 如果Out栈为空,把In栈数据压入Out栈
+ // In: 1 2 3 => pop push => 1 2 3 :Out
+ private function shift(){
+ while(!$this->stackIn->isEmpty()){
+ $this->stackOut->push($this->stackIn->pop());
+ }
+ }
+ }
+```
+
Scala:
```scala
class MyQueue() {
@@ -533,6 +580,7 @@ class MyQueue() {
def empty(): Boolean = {
stackIn.isEmpty && stackOut.isEmpty
}
+
}
```
-----------------------
diff --git a/problems/0283.移动零.md b/problems/0283.移动零.md
index 9600edd3..fe8e41c1 100644
--- a/problems/0283.移动零.md
+++ b/problems/0283.移动零.md
@@ -133,6 +133,27 @@ var moveZeroes = function(nums) {
};
```
+TypeScript:
+
+```typescript
+function moveZeroes(nums: number[]): void {
+ const length: number = nums.length;
+ let slowIndex: number = 0,
+ fastIndex: number = 0;
+ while (fastIndex < length) {
+ if (nums[fastIndex] !== 0) {
+ nums[slowIndex++] = nums[fastIndex];
+ };
+ fastIndex++;
+ }
+ while (slowIndex < length) {
+ nums[slowIndex++] = 0;
+ }
+};
+```
+
+
+
-----------------------
diff --git a/problems/0509.斐波那契数.md b/problems/0509.斐波那契数.md
index 71647a0a..785d0125 100644
--- a/problems/0509.斐波那契数.md
+++ b/problems/0509.斐波那契数.md
@@ -234,6 +234,7 @@ func fib(n int) int {
}
```
### Javascript
+解法一
```Javascript
var fib = function(n) {
let dp = [0, 1]
@@ -244,6 +245,23 @@ var fib = function(n) {
return dp[n]
};
```
+解法二:时间复杂度O(N),空间复杂度O(1)
+```Javascript
+var fib = function(n) {
+ // 动规状态转移中,当前结果只依赖前两个元素的结果,所以只要两个变量代替dp数组记录状态过程。将空间复杂度降到O(1)
+ let pre1 = 1
+ let pre2 = 0
+ let temp
+ if (n === 0) return 0
+ if (n === 1) return 1
+ for(let i = 2; i <= n; i++) {
+ temp = pre1
+ pre1 = pre1 + pre2
+ pre2 = temp
+ }
+ return pre1
+};
+```
TypeScript
diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md
index 2a4bd3b3..84061ef5 100644
--- a/problems/0541.反转字符串II.md
+++ b/problems/0541.反转字符串II.md
@@ -53,10 +53,10 @@ public:
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if (i + k <= s.size()) {
reverse(s.begin() + i, s.begin() + i + k );
- continue;
+ } else {
+ // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
+ reverse(s.begin() + i, s.end());
}
- // 3. 剩余字符少于 k 个,则将剩余字符全部反转。
- reverse(s.begin() + i, s.begin() + s.size());
}
return s;
}