合并k个有序链表
var mergeKLists = function(lists) {
let ans=null;
for(let i=0;i<lists.length;i++){
ans=mergeTwoLists(ans,lists[i]);
}
return ans;
};
function mergeTwoLists(list1,list2){//合并两个有序链表,递归
if(list1===null) return list2;
if(list2===null) return list1;
if(list1.val<=list2.val){
list1.next= mergeTwoLists(list1.next,list2);
return list1;
}else{
list2.next=mergeTwoLists(list1,list2.next);
return list2;
}
}
绝大多数链表题都是用双指针去做:
反转链表
第一行是暂存;第二行是改变箭头指向;后两行是移动指针。
var reverseList = function(head) {
if(head===null) return null;
let pre=null,cur=head;
let tmp;
while(cur!==null){
tmp=cur.next;//暂存cur的下一位
cur.next=pre;//反转箭头指向,使cur指向左边的pre
pre=cur;//先移动pre
cur=tmp;//再移动cur
}
return pre;
};
删除链表的结点
var deleteNode = function(head, val) {
if(head.val===val) return head.next;
let pre=null,cur=head;
while(cur.val!==val){
pre=cur;
cur=cur.next;
}
pre.next=cur.next;
return head;
};
不给head的情况:
var deleteNode = function(node) {
node.val=node.next.val;
node.next=node.next.next;
};
两个链表的第一个公共结点(相交链表)
var getIntersectionNode = function(headA, headB) {
if(headA===null||headB===null) return null;
let p1=headA,p2=headB;
while(p1!==p2){
p1= p1===null? headB:p1.next;
p2= p2===null? headA:p2.next;
}
return p1;
};
链表中环的入口结点(环形链表Ⅱ)!!!
var detectCycle = function(head) {
if(head===null||head.next===null) return null;
let slow=head,fast=head;
while(fast!==null&&fast.next!==null){
slow=slow.next;
fast=fast.next.next;
//如果相遇,即存在环
if(fast===slow){
let fast=head;
while(fast!==slow){
slow=slow.next;
fast=fast.next;
}
return fast;
}
}
return null;
};
链表中倒数第k个结点
var getKthFromEnd = function(head, k) {
let fast=slow=head;
let count=0;
while(fast!==null){
if(count>=k){
slow=slow.next;
}
fast=fast.next;
count++;
}
// if(count<k) return null;//此if对应while里的判断count>k的相反case
return slow;
};