总结一下最近做过的链表相关的题目(后续不定时更新内容)
1、反转链表
本题使用指针反转,其他的方法:可以先遍历head,把数据保存到数组中,数组反转,然后定义一个新指针类遍历复制即可。
1->2->3->4->5反转输出为:5->4->3->2->1
function ReverseList(pHead){
let pre = null;
let curr = pHead;
while(curr) {
const next = curr.next;
curr.next = pre;
pre = curr;
curr = next;
}
return pre;
}
2、删除链表中重复的数据(一)
1->1->2->3 删除后:1->2->3
function delete(head) {
if (head === null) return null;
let cur = head;
while(cur.next) {//注意
if (cur.val === cur.next.val) {
cur.next = cur.next.next; //重点
} else {
cur = cur.next;
}
}
return head;
}
3、删除链表中的重复的数据(二)
1->1->1->2->3->3->4->5 结果为:2->4->5
一般链表在做删除操作时,要定义一个pre的指针,next指向当前的指针cur
function deleteDuplication(pHead){
if (pHead === null) return null;
// let node = new ListNode(0, pHead); 第一种
let node = null; node.next = pHead;
let pre = node;
let cur = pHead;
while(cur) {
if (cur.next && cur.val === cur.next.val) {
cur = cur.next;//if已经相同了,,先移动一下
// 判断cur是否等于下一个值,如果是,一直判断
while(cur.next && cur.val === cur.next.val) {
cur = cur.next;
}
cur = cur.next; //让指针指到下一个元素,比如:cur循环出来是最后一个1,因为结果不需要1,所以要指向下一个元素2
pre.next = cur; //前一个指针的next指向当前不重复的值
} else {
pre =cur;
cur = cur.next;
}
}
return node.next;
}
4、删除链表中和指定元素相同的值
1->2->3->4->5, k = 4 结果为: 1->2->3->5
默认相同的值只有一个
function deleteNode(head, val) {
if (head === null) return null;
if (head.val === val) return head.next; //如果删除的是第一个节点
let pre = null; //指向上一个节点,删除时使用
let curr = head;
while(curr) {
if (curr.val === val) {
pre.next = curr.next;
return head; //如果删除多个重复的,可以替换为:curr = curr.next; return null -> return head
} else { //移动指针
pre = curr;
curr = curr.next;
}
}
return null;
}
5、删除链表中倒数第k个元素
2->5->1->9->3,k=2 结果为:2->5->1->3
var removeNthFromEnd = function(head, n) {
if (!head) return null;
let count = 0;
let cur = head;
while(cur) {//先遍历一遍,保存链表长度
count++;
cur = cur.next;
}
if (count - n === 0) return head.next; //如果是第一个元素的话,直接返回
let i = 0;//用来计数
let curr = head;
let pre = null;
while(curr) {
if (i === count - n) {
pre.next = curr.next;
return head;
}
i++;
pre = curr;
curr = curr.next;
}
return head;
};
6、链表是否有环
判断链表是否有环,这里使用快慢指针;也可以使用map保存起来,,遍历的时候看看是否在集合中存在
var hasCycle = function(head) {
if (!head || !head.next) return false;
let slow = head;
let fast = head.next.next;
while(fast && fast.next) {
if (slow === fast) return true;
slow = slow.next;
fast = fast.next.next;
}
return false;
};
7、链表中环的入口节点
function EntryNodeOfLoop(pHead){
let map = new Map(); //使用集合保存每个值
while(pHead) {
const val = pHead.val;
if (map.has(val)) {//判断是否存在过
return val;
}
map.set(val, val);
pHead = pHead.next;
}
return null;
}
8、判断两个链表是否相交
和上题的思路差不多,都是利用集合保存
两种解法:
1、判断两个链表的最后一个元素是否相等(各自循环查看)
2、集合保存值,查看是否存在过
var getIntersectionNode = function(headA, headB) {
const set = new Set();
let A = headA;
let B = headB;
while(A) {
set.add(A);
A = A.next;
}
while(B) {
if (set.has(B)) {
return B
}
B = B.next;
}
return null;
};
…后面陆续添加。。。