Skip to content

Commit e427568

Browse files
Merge branch 'youngyangyang04:master' into master
2 parents b072556 + 0b32570 commit e427568

8 files changed

+295
-4
lines changed

problems/0015.三数之和.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,76 @@ var threeSum = function(nums) {
345345
return res
346346
};
347347
```
348+
349+
解法二:nSum通用解法。递归
350+
351+
```js
352+
/**
353+
* nsum通用解法,支持2sum,3sum,4sum...等等
354+
* 时间复杂度分析:
355+
* 1. n = 2时,时间复杂度O(NlogN),排序所消耗的时间。、
356+
* 2. n > 2时,时间复杂度为O(N^n-1),即N的n-1次方,至少是2次方,此时可省略排序所消耗的时间。举例:3sum为O(n^2),4sum为O(n^3)
357+
* @param {number[]} nums
358+
* @return {number[][]}
359+
*/
360+
var threeSum = function (nums) {
361+
// nsum通用解法核心方法
362+
function nSumTarget(nums, n, start, target) {
363+
// 前提:nums要先排序好
364+
let res = [];
365+
if (n === 2) {
366+
res = towSumTarget(nums, start, target);
367+
} else {
368+
for (let i = start; i < nums.length; i++) {
369+
// 递归求(n - 1)sum
370+
let subRes = nSumTarget(
371+
nums,
372+
n - 1,
373+
i + 1,
374+
target - nums[i]
375+
);
376+
for (let j = 0; j < subRes.length; j++) {
377+
res.push([nums[i], ...subRes[j]]);
378+
}
379+
// 跳过相同元素
380+
while (nums[i] === nums[i + 1]) i++;
381+
}
382+
}
383+
return res;
384+
}
385+
386+
function towSumTarget(nums, start, target) {
387+
// 前提:nums要先排序好
388+
let res = [];
389+
let len = nums.length;
390+
let left = start;
391+
let right = len - 1;
392+
while (left < right) {
393+
let sum = nums[left] + nums[right];
394+
if (sum < target) {
395+
while (nums[left] === nums[left + 1]) left++;
396+
left++;
397+
} else if (sum > target) {
398+
while (nums[right] === nums[right - 1]) right--;
399+
right--;
400+
} else {
401+
// 相等
402+
res.push([nums[left], nums[right]]);
403+
// 跳过相同元素
404+
while (nums[left] === nums[left + 1]) left++;
405+
while (nums[right] === nums[right - 1]) right--;
406+
left++;
407+
right--;
408+
}
409+
}
410+
return res;
411+
}
412+
nums.sort((a, b) => a - b);
413+
// n = 3,此时求3sum之和
414+
return nSumTarget(nums, 3, 0, 0);
415+
};
416+
```
417+
348418
TypeScript:
349419

350420
```typescript

problems/0020.有效的括号.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,37 @@ bool isValid(char * s){
400400
return !stackTop;
401401
}
402402
```
403+
404+
405+
PHP:
406+
```php
407+
// https://www.php.net/manual/zh/class.splstack.php
408+
class Solution
409+
{
410+
function isValid($s){
411+
$stack = new SplStack();
412+
for ($i = 0; $i < strlen($s); $i++) {
413+
if ($s[$i] == "(") {
414+
$stack->push(')');
415+
} else if ($s[$i] == "{") {
416+
$stack->push('}');
417+
} else if ($s[$i] == "[") {
418+
$stack->push(']');
419+
// 2、遍历匹配过程中,发现栈内没有要匹配的字符 return false
420+
// 3、遍历匹配过程中,栈已为空,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
421+
} else if ($stack->isEmpty() || $stack->top() != $s[$i]) {
422+
return false;
423+
} else {//$stack->top() == $s[$i]
424+
$stack->pop();
425+
}
426+
}
427+
// 1、遍历完,但是栈不为空,说明有相应的括号没有被匹配,return false
428+
return $stack->isEmpty();
429+
}
430+
}
431+
```
432+
433+
403434
Scala:
404435
```scala
405436
object Solution {
@@ -422,5 +453,6 @@ object Solution {
422453
}
423454
}
424455
```
456+
425457
-----------------------
426458
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

problems/0189.旋转数组.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
# 189. 旋转数组
99

10+
[力扣题目链接](https://leetcode.cn/problems/rotate-array/)
11+
1012
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
1113

1214
进阶:
@@ -160,6 +162,27 @@ var rotate = function (nums, k) {
160162
};
161163
```
162164

165+
## TypeScript
166+
167+
```typescript
168+
function rotate(nums: number[], k: number): void {
169+
const length: number = nums.length;
170+
k %= length;
171+
reverseByRange(nums, 0, length - 1);
172+
reverseByRange(nums, 0, k - 1);
173+
reverseByRange(nums, k, length - 1);
174+
};
175+
function reverseByRange(nums: number[], left: number, right: number): void {
176+
while (left < right) {
177+
const temp = nums[left];
178+
nums[left] = nums[right];
179+
nums[right] = temp;
180+
left++;
181+
right--;
182+
}
183+
}
184+
```
185+
163186

164187

165188
-----------------------

problems/0225.用队列实现栈.md

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,6 @@ class MyStack {
816816
}
817817
```
818818
Scala:
819-
820819
使用两个队列模拟栈:
821820
```scala
822821
import scala.collection.mutable
@@ -897,6 +896,86 @@ class MyStack() {
897896
def empty(): Boolean = {
898897
queue.isEmpty
899898
}
899+
}
900+
```
901+
902+
903+
PHP
904+
> 双对列
905+
```php
906+
// SplQueue 类通过使用一个双向链表来提供队列的主要功能。(PHP 5 >= 5.3.0, PHP 7, PHP 8)
907+
// https://www.php.net/manual/zh/class.splqueue.php
908+
class MyStack {
909+
public $queueMain; // 保存数据
910+
public $queueTmp; // 辅助作用
911+
912+
function __construct() {
913+
$this->queueMain=new SplQueue();
914+
$this->queueTmp=new SplQueue();
915+
}
916+
917+
// queueMain: 1,2,3 <= add
918+
function push($x) {
919+
$this->queueMain->enqueue($x);
920+
}
921+
922+
function pop() {
923+
$qmSize = $this->queueMain->Count();
924+
$qmSize --;
925+
// queueMain: 3,2,1 => pop =>2,1 => add => 2,1 :queueTmp
926+
while($qmSize --){
927+
$this->queueTmp->enqueue($this->queueMain->dequeue());
928+
}
929+
// queueMain: 3
930+
$val = $this->queueMain->dequeue();
931+
// queueMain <= queueTmp
932+
$this->queueMain = $this->queueTmp;
933+
// 清空queueTmp,下次使用
934+
$this->queueTmp = new SplQueue();
935+
return $val;
936+
}
937+
938+
function top() {
939+
// 底层是双链表实现:从双链表的末尾查看节点
940+
return $this->queueMain->top();
941+
}
942+
943+
function empty() {
944+
return $this->queueMain->isEmpty();
945+
}
946+
}
947+
```
948+
> 单对列
949+
```php
950+
class MyStack {
951+
public $queue;
952+
953+
function __construct() {
954+
$this->queue=new SplQueue();
955+
}
956+
957+
function push($x) {
958+
$this->queue->enqueue($x);
959+
}
960+
961+
function pop() {
962+
$qmSize = $this->queue->Count();
963+
$qmSize --;
964+
//queue: 3,2,1 => pop =>2,1 => add => 2,1,3 :queue
965+
while($qmSize --){
966+
$this->queue->enqueue($this->queue->dequeue());
967+
}
968+
$val = $this->queue->dequeue();
969+
return $val;
970+
}
971+
972+
function top() {
973+
return $this->queue->top();
974+
}
975+
976+
function empty() {
977+
return $this->queue->isEmpty();
978+
}
900979
}
901980
```
902981
-----------------------

problems/0232.用栈实现队列.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,53 @@ void myQueueFree(MyQueue* obj) {
495495
obj->stackOutTop = 0;
496496
}
497497
```
498+
499+
500+
PHP:
501+
```php
502+
// SplStack 类通过使用一个双向链表来提供栈的主要功能。[PHP 5 >= 5.3.0, PHP 7, PHP 8]
503+
// https://www.php.net/manual/zh/class.splstack.php
504+
class MyQueue {
505+
// 双栈模拟队列:In栈存储数据;Out栈辅助处理
506+
private $stackIn;
507+
private $stackOut;
508+
509+
function __construct() {
510+
$this->stackIn = new SplStack();
511+
$this->stackOut = new SplStack();
512+
}
513+
514+
// In: 1 2 3 <= push
515+
function push($x) {
516+
$this->stackIn->push($x);
517+
}
518+
519+
function pop() {
520+
$this->peek();
521+
return $this->stackOut->pop();
522+
}
523+
524+
function peek() {
525+
if($this->stackOut->isEmpty()){
526+
$this->shift();
527+
}
528+
return $this->stackOut->top();
529+
}
530+
531+
function empty() {
532+
return $this->stackOut->isEmpty() && $this->stackIn->isEmpty();
533+
}
534+
535+
// 如果Out栈为空,把In栈数据压入Out栈
536+
// In: 1 2 3 => pop push => 1 2 3 :Out
537+
private function shift(){
538+
while(!$this->stackIn->isEmpty()){
539+
$this->stackOut->push($this->stackIn->pop());
540+
}
541+
}
542+
}
543+
```
544+
498545
Scala:
499546
```scala
500547
class MyQueue() {
@@ -533,6 +580,7 @@ class MyQueue() {
533580
def empty(): Boolean = {
534581
stackIn.isEmpty && stackOut.isEmpty
535582
}
583+
536584
}
537585
```
538586
-----------------------

problems/0283.移动零.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,27 @@ var moveZeroes = function(nums) {
133133
};
134134
```
135135

136+
TypeScript:
137+
138+
```typescript
139+
function moveZeroes(nums: number[]): void {
140+
const length: number = nums.length;
141+
let slowIndex: number = 0,
142+
fastIndex: number = 0;
143+
while (fastIndex < length) {
144+
if (nums[fastIndex] !== 0) {
145+
nums[slowIndex++] = nums[fastIndex];
146+
};
147+
fastIndex++;
148+
}
149+
while (slowIndex < length) {
150+
nums[slowIndex++] = 0;
151+
}
152+
};
153+
```
154+
155+
156+
136157

137158
-----------------------
138159
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

problems/0509.斐波那契数.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ func fib(n int) int {
234234
}
235235
```
236236
### Javascript
237+
解法一
237238
```Javascript
238239
var fib = function(n) {
239240
let dp = [0, 1]
@@ -244,6 +245,23 @@ var fib = function(n) {
244245
return dp[n]
245246
};
246247
```
248+
解法二:时间复杂度O(N),空间复杂度O(1)
249+
```Javascript
250+
var fib = function(n) {
251+
// 动规状态转移中,当前结果只依赖前两个元素的结果,所以只要两个变量代替dp数组记录状态过程。将空间复杂度降到O(1)
252+
let pre1 = 1
253+
let pre2 = 0
254+
let temp
255+
if (n === 0) return 0
256+
if (n === 1) return 1
257+
for(let i = 2; i <= n; i++) {
258+
temp = pre1
259+
pre1 = pre1 + pre2
260+
pre2 = temp
261+
}
262+
return pre1
263+
};
264+
```
247265

248266
TypeScript
249267

problems/0541.反转字符串II.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ public:
5353
// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
5454
if (i + k <= s.size()) {
5555
reverse(s.begin() + i, s.begin() + i + k );
56-
continue;
56+
} else {
57+
// 3. 剩余字符少于 k 个,则将剩余字符全部反转。
58+
reverse(s.begin() + i, s.end());
5759
}
58-
// 3. 剩余字符少于 k 个,则将剩余字符全部反转。
59-
reverse(s.begin() + i, s.begin() + s.size());
6060
}
6161
return s;
6262
}

0 commit comments

Comments
 (0)