1.链表
1.反转链表1
2.反转链表2
(跳转:leetcode.cn/problems/re… )
析:
我们在一开始对链表进行遍历的时候就可以根据left和right找到“四个指针”,并用四个变量记录下来:区间的头指针,区间的尾指针,左断点、右断点。
关键点1: 记录左右两个断点。我们反转了区间链表之后怎么和未反转的部分“相连”。所以我们需要两个变量来记录与区间相连的两个左右断点。原来与反转区间相连的“左断点”和“右断点”。只要将左断点的next指向反转后的“头指针”,将反转后的“尾指针”的next指向右断点,就可以完成相连。
关键点2: 找到区间,并隔断连接处,使其成为完整链表,然后进行完整链表的反转操作。我们执行链表的操作比较擅长的是反转完整链表,所以我们需要将区间与断点割裂,并在头尾两端连接null,那么我们就可以调用反转整个链表的函数。
关键点3: 连接
反转的核心思路是找到要反转的区间(这个区间的头指针和尾指针),然后对这个区间进行反转,反转之后原来的头指针变成了“尾指针”,原来的尾指针变成了“头指针”。并且我们也记录了左右断点,所以连结就是将左断点的next指向尾指针,头指针的next指向右断点
var reverseBetween = function(head, left, right) {
const vnode = new ListNode(-1);
vnode.next = head;
// 先创建一个虚拟节点,指向这个链表,防止left是链表开头这种边界情况,那么pre和left就指向同一个
// step1: 寻找左断点
let leftPoint = vnode; // 左断点赋初始值
for (let index = 1; index < left; index++) {
leftPoint = leftPoint.next
}
// step2: 找到中间链表的头节点
let part_head = leftPoint.next;
// step3: 寻找链表的尾节点
let part_end = part_head;
for (let index = left; index < right; index++) {
part_end = part_end.next;
}
// step4: 找到右断点
let rightPoint = part_end.next;
// step5: 断开链表
leftPoint.next = null;
part_end.next = null;
// step6:反转区间链表
reverse(part_head)
function reverse(head) {
let pre = null;
let cur = head;
while(cur) {
let next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
leftPoint.next = part_end;
part_head.next = rightPoint;
return vnode.next
};
3.删除链表中的节点
4.删除链表的倒数第 n 个结点
(跳转:leetcode.cn/problems/SL… )
5.两两交换链表中的节点
6.合并两个有序链表(扩展到合并k个有序链表)
var deleteNode = function(head, val) {
let link = head1 = new ListNode()
link.next = head;
while(link.next) {
if (link.next.val === val) {
link.next = link.next.next;
} else {
link = link.next;
}
}
return head1.next;
};
[链表中倒数第k个节点]
2.栈
1.验证栈序列
思路:这题本质上是通过一个入栈的最终结果表,能否判断出这个栈在这一过程中(经历入栈和出栈),最终形成的出栈表是否为给定这个表。
例如,我对一个栈执行一系列的入栈出栈操作,最终将这个栈全部出栈,得到的结果是不是给定的出栈结果。 这一系列出栈入栈操作为:入栈1,2,3,4,出栈4,入栈5,出栈5,出栈3,2,1 我们通过栈的特点可以发现,pop这个出栈结果中的第一位一定是最先从pushed中pop的。为什么?因为加入我一开始全部执行入栈操作,还没有执行pop操作,那么第一个执行pop操作的元素,一定是放在poped数组的第一位(这里poped数组是指将出栈的元素push入栈),然后poped第二个元素就是pushed中第二个出栈的。那么我们需要做的就是通过poped的结果来逆向模拟这一系列入栈出栈的过程,最后如果这个pushed栈为空,那么就是一一对应,否则,两个不对应。
var validateStackSequences = function(pushed, popped) {
let index2 = 0;
let stack = [];
for (let index = 0; index < pushed.length; index++) {
stack.push(pushed[index]);
while (stack.length > 0 && stack[stack.length - 1] === popped[index2]) {
stack.pop();
index2++;
}
}
return stack.length === 0
};