const hasCycle = (r) => {
if (!r || !r.next) return false
let fast = r.next.next, slow = r.next;
while (fast !== slow) {
if (!fast || !fast.next) return false
fast = fast.next.next
slow = slow.next
}
// 如需找到环入口只需新建一个指针tmp和slow指针同时向前遍历,当两者相等时,入口就是tmp
return true
}
const getMiddle = (r) => {
if (!r || !r.next) return r;
let fast = r, slow = r;
while (fast && fast.next) {
fast = fast.next.next;
slow = slow.next
}
return slow
}
const reverse = (r) => {
if (!r || !r.next) return r;
let prev = null, cur = r;
while (cur) {
// 用于临时存储 cur 后继节点
// 否则下一步就会抹掉原来的cur.next
let next = cur.next; // 4
// 反转 cur 的后继指针
cur.next = prev; // 首个节点的next就变为了null
// 变更prev、cur
prev = cur; // prev前移
cur = next // cur前移
}
r = prev;
return r;
}
const reverse = (r) => {
const _reverse = function (prev, cur) {
if (!cur) return prev // 前移的时候cur为null就结束了
// 临时存储
let next = cur.next;
// 核心反转
cur.next = prev;
return _reverse(cur, next) // prev,cur => cur, next
}
if (!r || !r.next) return r;
r = _reverse(null, r);
return r;
}
const addTwoNumbers = (l1, l2) => {
let carry = 0;
let head = null, tail = null; // 当carry>0时,tail用于表示进位
while (l1 || l2) {
let n1 = l1 ? l1.ele : 0;
let n2 = l2 ? l2.ele : 0;
let sum = n1 + n2 + carry;
if (!head) {
head = tail = new Node(sum % 10);
} else {
tail.next = new Node(sum % 10);
tail = tail.next
}
carry = (sum / 10) >> 0
// console.log('ele', sum, l1.ele, l2.ele)
if (l1) {
l1 = l1.next;
}
if (l2) {
l2 = l2.next;
}
}
// 如果有进位,附加一个新节点,其值为carry
if (carry) {
tail.next = new Node(carry)
}
return head
}
var isPalindrome = function (head) {
const arr = [];
while (head) {
arr.push(head.val);
head = head.next;
}
let i = 0,
len = arr.length,
j = len - 1;
for (i, j; i < j; i++, j--) {
if (arr[i] !== arr[j]) {
return false;
}
}
return true;
};
var isPalindrome = function (head) {
let slow = head,
fast = head;
let prev = null,
next = null;
while (fast !== null && fast.next !== null) {
fast = fast.next.next;
next = slow.next;
// slow 边走边逆序
slow.next = prev;
prev = slow;
slow = next;
}
if (fast !== null) {
// 链表长度为奇数
slow = slow.next;
}
while (prev !== null && slow !== null) {
if (prev.val !== slow.val) {
return false;
}
prev = prev.next;
slow = slow.next;
}
return true;
};
var sortList = function (head) {
// 自顶向下归并排序
// 1. 找到链表的中点,以中点为分界,将链表拆分成两个子链表。
// 寻找链表的中点可以使用快慢指针的做法,快指针每次移动 22 步,慢指针每次移动 11 步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点
// 2. 对两个子链表分别排序。
// 3. 将两个排序后的子链表合并,得到完整的排序后的链表
return toSortList(head, null);
};
var toSortList = function (head, tail) {
if (!head || !head.next) {
return head;
}
if (head.next === tail) {
head.next = null;
return head;
}
// let slow = head.next;
// let fast = head.next.next;
// while (fast && fast.next && fast !== tail) {
// slow = slow.next;
// fast = fast.next.next;
// }
let slow = head,
fast = head;
while (fast !== tail) {
slow = slow.next;
fast = fast.next;
if (fast !== tail) {
fast = fast.next;
}
}
const mid = slow;
return mergeTwoList(toSortList(head, mid), toSortList(mid, tail));
};