开始刷题
160. 相交链表
双指针法,遍历完一遍后,指向另一个链表的头。a+b=b+a,有交点就一定会在交点处相遇,分两种情况,链表长度相等与不相等分析。
var getIntersectionNode = function (headA, headB) {
let pA = headA, pB = headB;
while (pA !== pB) {
pA = pA === null ? headB : pA.next;
pB = pB === null ? headA : pB.next;
}
return pA;
};
206. 反转链表
迭代法、还可用递归
var reverseList = function (head) {
let pre = null;
let current = head;
while (current) {
const next = current.next;
current.next = pre;
pre = current;
current = next;
}
return pre;
};
21. 合并两个有序链表
迭代法、还可用递归
var mergeTwoLists = function (l1, l2) {
let prehead = new ListNode(-1);
let pre = prehead;
while (l1 && l2) {
if (l1.val <= l2.val) {
pre.next = l1;
l1 = l1.next;
} else {
pre.next = l2;
l2 = l2.next;
}
pre = pre.next;
}
if (l1 || l2) {
pre.next = l1 === null ? l2 : l1;
}
return prehead.next;
};
83. 删除排序链表中的重复元素
可优化,一个指针即可
var deleteDuplicates = function (head) {
if(!head)return null;
let pre = head;
let currrnt = head.next;
while (currrnt) {
if (pre.val === currrnt.val) {
pre.next = currrnt.next;
currrnt.next = null;
currrnt = pre.next;
continue;
}
pre = pre.next;
currrnt = currrnt.next;
}
return head;
};
19. 删除链表的倒数第 N 个结点
1.计算链表长度 2.栈 3.快慢指针 ,这里用快慢指正实现
var removeNthFromEnd = function (head, n) {
let fast = head;
while (n--) {
fast = fast.next;
}
if(!fast) return head.next; //如果删除的是第一个节点
let slow = head;
while (fast.next) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
};
24. 两两交换链表中的节点
每次要改变3各节点的指向,需要三个临时变量。
var swapPairs = function (head) {
const newHead = new ListNode(-1);
newHead.next = head;
let temp = newHead;
while (temp.next && temp.next.next) {
let first = temp.next;
let second = temp.next.next;
temp.next = second;
first.next = second.next;
second.next = first;
temp = first;
}
return newHead.next;
};
445. 两数相加 II
1.翻转链表 2.栈 (逆序可以用栈)
存入栈的方法可以提炼出来
var addTwoNumbers = function (l1, l2) {
let stack1 = [];
let stack2 = [];
while (l1) {
stack1.push(l1.val);
l1 = l1.next;
}
while (l2) {
stack2.push(l2.val);
l2 = l2.next;
}
let carry = 0;
let newhead = new ListNode(-1);
while (stack1.length || stack2.length || carry != 0) { //carry有进位注意
let x = stack1.length > 0 ? stack1.pop() : 0;
let y = stack2.length > 0 ? stack2.pop() : 0;
let sum = x + y + carry;
carry = Math.floor(sum / 10);
let node = new ListNode(sum % 10);
node.next = newhead.next;
newhead.next = node;
}
return newhead.next;
};
234. 回文链表
1.放到数组中,双指针比较 2.快慢指针,将链表分成两段,后一段翻转后比较。
var isPalindrome = function (head) {
let p = head;
let stack = [];
while (p) {
stack.push(p.val);
p = p.next;
}
let left = 0;
let right = stack.length - 1;
while (left <= right) {
if (stack[left] != stack[right]){
return false;
}
left++;
right--;
}
return true;
};
725. 分隔链表
var splitListToParts = function (root, k) {
let p1 = root;
let count = 0;
//获取链表长度
while (p1) {
count++;
p1 = p1.next;
}
let res = [];
let head = root; //当前组表头
let current = root; //移动指针
let nexthead = root; //下一组的表头
//遍历k次,结果放入res
for (let i = 0; i < k; i++) {
let less = Math.floor(count / k);
let more = count % k;
//确定每组数量,前几组加一
if (i < more) {
less = less + 1;
}
//根据数量切出单个组
while (less > 0) {
less--;
if (less === 0) {
nexthead = current.next; //得到下一组的表头
current.next = null; //当前组最后一个指向null
}
current = current.next;
}
res.push(head);
head = nexthead;
current = nexthead;
}
return res;
};
328. 奇偶链表
var oddEvenList = function (head) {
if (!head) return null;
let odd = head, even = head.next, evenHead = even;
while (even && even.next) {
odd.next = odd.next.next;
odd = odd.next;
even.next = even.next.next;
even = even.next;
}
odd.next = evenHead;
return head;
};