Skip to content

Commit

Permalink
docs: update
Browse files Browse the repository at this point in the history
docs: update

docs: update
  • Loading branch information
brightzoe committed Mar 26, 2024
1 parent f4727b8 commit 5efaae9
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 0 deletions.
75 changes: 75 additions & 0 deletions docs/algorithm/list-problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,78 @@ const three = new ListNode(3);
const two = new ListNode(2, three);
const one = new ListNode(1, two);
```
[92. 反转链表 II - 力扣(LeetCode)](https://leetcode.cn/problems/reverse-linked-list-ii/)
- 局部反转链表。是上一题的加强版,利用多指针。第一种思路,找到开始节点,和preNode,找到结束节点和nextNode。将链表切成三部分,将中间切开的部分进行反转,然后preNode.next = newStart;start.next = nextNode 进行拼接。思路顺畅但编码量稍多。
- 第二种思路,同样是遍历链表,找到preNode,原地将left-node段进行反转。使用pre,curr的快慢指针遍历反转。然后特殊处理两个边界,
> 注意添加dummy节点简化思路。
```ts
//拆分为三段
function reverseBetween(
head: ListNode | null,
left: number,
right: number,
): ListNode | null {
let dummy = new ListNode(0, head);
let pre = dummy;
for (let i = 0; i < left - 1; i++) {
pre = pre.next;
}
let start = pre.next;
let end = pre;
for (let i = 0; i < right - left + 1; i++) {
end = end.next;
}
let next = end.next;
end.next = null;
pre.next = null;
reverse(start);

pre.next = end;

start.next = next;

return dummy.next;
}

function reverse(head: ListNode) {
let pre = null;
let curr = head;
while (curr) {
const next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
}
```
```ts
// 不拆分直接反转
function reverseBetween(
head: ListNode | null,
left: number,
right: number,
): ListNode | null {
let dummy = new ListNode(0, head);
let leftPre = dummy;
for (let i = 0; i < left - 1; i++) {
leftPre = leftPre.next;
}
let start = leftPre.next;
let pre = start;
let curr = start.next;
for (let i = left; i < right; i++) {
const next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
leftPre.next = pre;
start.next = curr;
return dummy.next;
}
```
146 changes: 146 additions & 0 deletions docs/algorithm/stack-problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# 栈和队列

##

[20. 有效的括号 - 力扣(LeetCode)](https://leetcode.cn/problems/valid-parentheses/)

- 对称性。利用栈,先入栈的后出栈。栈的后进先出原则,一组数据的入栈和出栈顺序刚好是对称的。

```ts
function isValid(s: string): boolean {
// 边界
if (!s.length) {
return true;
}
// Map或者obj都是可以的
const map = new Map([
['(', ')'],
['[', ']'],
['{', '}'],
]);
let stack = [];
for (let i = 0; i < s.length; i++) {
// 是左边的括号直接进入
if (map.has(s[i])) {
stack.push(s[i]);
} else {
// 是右边的括号但无法出栈直接返回
if (s[i] !== map.get(stack.pop())) {
return false;
}
}
}
// 是不是空栈
return !stack.length;
}
```

## 单调栈

[739. 每日温度 - 力扣(LeetCode)](https://leetcode.cn/problems/daily-temperatures/submissions/516316386/)

- 暴力解法,循环套循环,超时。
- 维护一个递减的栈。循环一次,每次将当前元素与栈顶元素比较,若栈顶元素小于当前元素,则将栈顶元素出栈,并计算差值。直到栈顶元素大于等于当前元素,将当前元素入栈。

```ts
// 维护递减的栈
function dailyTemperatures(temperatures: number[]): number[] {
const res = new Array(temperatures.length).fill(0);
// 递减栈,维护的是每天的索引而不是温度,比较好计算
const stack: number[] = [];

for (let i = 0; i < temperatures.length; i++) {
// 当前温度大于栈顶的温度
while (
stack.length &&
temperatures[i] > temperatures[stack[stack.length - 1]]
) {
const top = stack.pop()!;
// 栈顶的索引放入结果中,值为i-top
res[top] = i - top;
}
stack.push(i);
}
return res;
}
```

[155. 最小栈 - 力扣(LeetCode)](https://leetcode.cn/problems/min-stack/description/)

- 设计一个数据结构,支持push/pop等,并能够检索到最小值。getMin可以通过一遍循环实现,时间复杂度O(n),空间复杂度O(1)。利用空间换时间,多维护一个递减栈,将最小值放在栈顶。getMin直接从栈顶拿。

```ts
class MinStack {
stack: number[];
minStack: number[];
constructor() {
this.stack = [];
this.minStack = [];
}
push(val: number) {
this.stack.push(val);
const min = this.minStack[this.minStack.length - 1];
// 当前值更小,推入递减栈 注意边界条件
if (this.minStack.length === 0 || val <= min) {
this.minStack.push(val);
}
}
pop() {
const top = this.stack.pop();
const min = this.minStack[this.minStack.length - 1];
// 小数走了,把对应的递减值推出去 注意边界条件
if (this.minStack.length > 0 && top === min) {
this.minStack.pop();
}
}
top() {
return this.stack[this.stack.length - 1];
}
getMin() {
console.log(this.minStack);
return this.minStack[this.minStack.length - 1];
}
}
```

## 用栈实现队列

[232. 用栈实现队列 - 力扣(LeetCode)](https://leetcode.cn/problems/implement-queue-using-stacks/submissions/516876214/)

- 用两个栈倒过来倒过去。

```ts
class MyQueue {
private stack1: number[];
private stack2: number[];
constructor() {
this.stack1 = [];
this.stack2 = [];
}
push(val: number) {
this.stack1.push(val);
}

peek() {
if (this.stack2.length === 0) {
while (this.stack1.length) {
const last = this.stack1.pop()!;
this.stack2.push(last);
}
}
return this.stack2[this.stack2.length - 1];
}
pop() {
if (this.stack2.length === 0) {
while (this.stack1.length) {
const last = this.stack1.pop()!;
this.stack2.push(last);
}
}
return this.stack2.pop();
}
empty() {
return this.stack1.length === 0 && this.stack2.length === 0;
}
}
```

0 comments on commit 5efaae9

Please sign in to comment.