「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」
前言
死磕算法,每天至少一道算法题,今天再把我们的誓言延伸一下,能把算法写出来没啥,能让别人听懂,看懂,并掌握才算自己真正的懂了,加油💪🏻
昨天我们讲了快慢指针,今天我们来讲多指针,有些小伙伴可能在想,快慢指针都已经很头疼了,咋还玩多指针。其实我们学东西的时候,要学会这个东西的使用场景,什么时候往这上面套,就会用的得心应手了
题目
这是leetcode上的第206道题目206. 反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
多指针
多指针其实并没有那么复杂,其实也就是多个变量,所指向不同的节点
适用场景:反转链表
思路
第一步:从题中提取关键字
这次没啥可提取的,直接分析吧
第二步:分析
- 1.我们前面说过做链表题无论是合并,删除等操作都是操作next指针,今天这句话要改一下,加上反转,哈哈😝
- 2.当前这道题如果要反转的话,比如3节点要反转的话,那么就把next改成指向2,但是问题来了,如果改成2的话,那么没法往下循环了,桥断了
- 3.所以在拆桥之前,我们要先把对岸也就是4节点保存起来,然后再拆
我们还是先写框架
var reverseList = function(head) {
// 这是必须有的
if(!head||!head.next){
return head;
}
let dummy = new ListNode();
dummy.next = head;
let cur = dummy;
while(执行条件){
// 循环
cur = cur.next;
}
return dummy.next;
};
开始填写内容,定义pre,cur,next三个指针
// 注意初始pre必须是null,因为他是反转后的最后一个元素
let pre = null;
let cur = dummy.next;
while(cur){
// next不能写到外面,如果cur为null的话,那么cur.next就报错了
let next = cur.next;
}
题解
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
// 这是必须有的
if(!head||!head.next){
return head;
}
let dummy = new ListNode();
dummy.next = head;
// 注意初始pre必须是null,因为他是反转后的最后一个元素
let pre = null;
let cur = dummy.next;
// 只要cur.val不为null,就继续遍历
while(cur){
let next = cur.next;
// 改变指针指向
cur.next = pre;
// 更新前节点
pre = cur;
// 更新当前节点
cur = next;
}
return pre;
};
总结
我觉得这种方法还是比较好理解的
- 第一步:先写出基本框架
- 第二步:定义三个节点(
记住:反转链表需要三个节点) - 第三部:改变指针指向,再把三个节点的值更新一下,next在while中更新
看了提交后的时间复杂度
还是比较符合预期的