考点系列必须会的三点:
1.遍历
2.删除
3.插入
考点解法:
快慢指针法
双指针法
递归方法
set方法
虚拟指针法
考点系列一:反转系列:
1.反转链表
2.局部反转链表
3.K个一组翻转链表
解法:
核心点:
整个链表的反转的源码背过最好,
var cur = head;
var pre = null;
while(cur){
var temp = cur.next;
cur.next= pre;
pre = cur;
cur = temp;
}
return pre;
之后的2,或是3无非就是链表的删除与拼接而已。
删除过程的模板如下,例如局部范围的删除:
var newNode = new ListNode();
newNode.next = head;
var preLeftNode = newNode;
i=1;
while(preLeftNode&&i<left){
preLeftNode = preLeftNode.next;
i++;
}
var rightNode = preLeftNode.next
var k=1;
while(rightNode&&(k<right-left+1)){
rightNode = rightNode.next;
k++;
}
var leftNode = preLeftNode.next;
var temp =rightNode.next;
preLeftNode.next = null;
rightNode.next = null;
preLeftNode.next = reverse(leftNode)
leftNode.next = temp
return newNode.next;
删除left-right之间范围的节点,因为存在删除的边界节点所以要用创建虚拟节点的方法进行解决。
其次删除过程中要保存前节点以及right节点之后的节点。替换的时候采用穿针引线的方法。
其次k的选值都要采用i=1一般i=0的时候处理的是链表的长度。
考点系列二:环形系列
1.环形链表
2.环形链表的起始位置
解法:标准的快慢指针法&hashMap法
set集合大法
var setMap = new Set();
var temp = head;
while(temp){
if(setMap.has(temp)){
return temp;
}
setMap.add(temp);
temp = temp.next;
}
return null;
快慢指针法
if(head==null||head.next==null){
return null;
}
var slow = head;
var fast = head;
while(fast&&fast.next){
fast = fast.next.next;
slow = slow.next;
if(fast==slow){
break;
}
}
if(fast!=slow){
return null;
}
fast = head;
while(slow!=fast){
fast = fast.next;
slow = slow.next;
}
return slow;
考点系列三:排序系列&合并链表
1.给链表排序
2.有序链表的合并
3.给链表进行插入排序
3.合并两个链表
4.合并K个升序链表
合并两个链表
解法:虚拟指针法
var mergeInBetween = function(list1, a, b, list2) {
var newHead= new ListNode();
newHead.next = list1;
var temp = newHead;
var i=0;
while(temp.next&&i<a){
temp = temp.next;
i++;
}
var k=0;
var obj = temp;
while(obj&&k<(b-a+1)){
obj = obj.next;
k++;
}
var left = temp;
var right = obj.next;
temp.next = null;
obj.next = null;
var aa = list2;
while(aa.next){
aa = aa.next;
}
left.next = list2;
if(aa){
aa.next = right;
}
return newHead.next
};
合并K个升序链表
var mergeKLists = function(lists) {
if(!lists.length){
return null;
}
var i=1;
var temp = lists[0];
while(i<lists.length){
temp = mergLinkTwo(temp,lists[i])
i++;
}
return temp;
};
var mergLinkTwo = function(left,right){
var dumpy = new ListNode();
var p = dumpy;
while(left&&right){
if(left.val<=right.val){
p.next = left;
left = left.next;
} else {
p.next = right;
right = right.next;
}
p = p.next;
}
if(left){
p.next = left;
}
if(right){
p.next = right;
}
return dumpy.next;
}
考点系列四:链表相交系列
1.链表相交系列
解法:双指针法
var lenA = getLength(headA);
var lenB = getLength(headB);
while(lenA!=lenB){
if(lenA>lenB){
headA = headA.next;
lenA--
} else {
headB = headB.next;
lenB--
}
}
while(headA){
if(headA==headB){
return headB;
}
headB = headB.next;
headA = headA.next;
}
return null
};
var getLength = function(head){
var i=0;
while(head){
head = head.next;
i++;
}
return i;
考点系列五:删除元素
1.移除重复节点
2.删除排序链表中的重复元素只保留一个
3.删除排序链表中的重复元素一个都不保留
4.删除链表的节点
考点系列六:分割链表
1.分割链表
2.分隔链表
核心思想:双指针解法
var partition = function(head, x) {
var temp = head;
var minNode = new ListNode(0);
var maxNode = new ListNode(0);
var minHead = minNode;
var maxHead = maxNode;
while(temp){
if(temp.val >= x){
maxNode.next = temp;
maxNode = maxNode.next;
} else {
minNode.next = temp;
minNode = minNode.next;
}
temp = temp.next;
}
maxNode.next = null;
minNode.next = maxHead.next;
return minHead.next
};
分隔列表:核心在于中间断接再连的过程
var splitListToParts = function(root, k) {
var length = getLen(root);
var list =[];
if(k>length){
for (i=0;i<k;i++){
if(root){
list[i] = root;
var temp = root.next;
root.next = null;
root = temp;
} else {
list[i] = null;
}
}
} else {
var count = Math.floor(length/k)
var reminder = length%k;
for(var i=0;i<k;i++){
list[i] = root;
for(var j=0;j<count+(reminder>0?1:0);j++){
root = root.next;
}
var temp = root.next;
root.next = null;
root = temp;
} }
return list;
};
var getLen = function(head){
var i=0;
var temp = head;
while(temp){
temp = temp.next
i++
}
return i;
}
考点系列七:回文链表相关
1.判断链表是否是回文链表
解法核心思想:快慢指针。
var isPalindrome = function(head) {
var fast = head;
var slow = head;
while(fast&&slow&&fast.next){
fast = fast.next.next;
slow = slow.next;
}
if(fast){
slow = slow.next;
}
var slow = trase(slow);
var pre = head;
while(slow){
if(pre.val!=slow.val){
return false }
pre = pre.next;
slow = slow.next;
}
return true;};
var trase = function(head){
var cur = head;
var pre= null;
while(cur){
var temp = cur.next;
cur.next= pre;
pre = cur;
cur = temp;
}
return pre;
}
考点八:任意链表节点交换
1.交换链表中的节点
解法核心:递归
var swapPairs = function(head) {
if(head==null||head.next==null){
return head;
}
var newHead = head.next;
head.next = swapPairs(head.next.next);
newHead.next = head;
return newHead;
};
考点系列九:两数相加
1.两数相加