141. 环形链表
解题思路
- 需要了解链表基础
- 使用快慢指针,一个一次走两步、一个一次走一步,如果相遇说明有环
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if(!head) {return false}
let p = head;
let fast = head.next;
while(fast && fast.next) {
if(p === fast) {
return true;
}
p = p.next;
fast = fast.next.next;
}
return false;
};
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if(!head) {return false}
let p = head;
let fast = head.next;
// 稍许不同的写法
while(p != fast && fast && fast.next) {
if(p === fast) {
return true;
}
p = p.next;
fast = fast.next.next;
}
return p === fast;
};
142. 环形链表 II
解题思路
- 先使用快慢指针找到相遇位置
- 如果找到,相遇位置,快慢指针都开始使用相同的速度前进,如果再次相遇,就说明是环的起点
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if(!head || !head.next) {
return null;
}
let p = head.next;
let fast = head.next.next;
while(fast !== p && fast && fast.next ) {
p = p.next;
fast = fast.next.next;
}
if(fast !== p) {
return null;
}
p = head;
while(p !== fast && p) {
p = p.next;
fast = fast.next;
}
return p;
};
206. 反转链表
解题思路
- 维护两个指针,依次反转节点 入: 1->null 第二次 2->1->null
- 依次类推达到翻转所有节点
/**
* 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 pre = null;
let cur = head;
while(cur) {
// 把当前节点的下个节点记录下来
const next = cur.next;
// 把当前节点的前个节点 反转 成下个节点
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
};
/**
* 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 pre = head;
let tail = head.next;
console.log(pre.val,tail.val,'up')
let p = reverseList(head.next);
console.log(pre.val,tail.val,'down')
pre.next = null;
tail.next = pre;
return p;
};
24. 两两交换链表中的节点
解题思路
- 定义一个函数,使用函数对于节点和它的下一个节点进行交换
- 比如
helper(1)
处理1 -> 2
,并且把交换变成2 -> 1
的尾节点1
的next
继续指向helper(3)
也就是交换后的4 -> 3
。
/**
* 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 swapPairs = function(head) {
if(!head || !head.next) {return head}
// 使用helper进行两两反转
const helper = (node) => {
const tempNext = node.next;
if(tempNext) {
const tempNextNext = node.next.next;
node.next.next = node;
if(tempNextNext) {
node.next = helper(tempNextNext)
} else {
node.next = null;
}
}
return tempNext || node;
}
return helper(head)
};