我自己写的和看的题解,速度内存差不多,但题解好理解
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
var pre=head,p=head;
while(p!=null)
{
if(p.val==val)
{
if(p!=head)
{
pre.next=p.next;
}
else
{
head=p.next;
pre=p;
}
}
else
{
pre=p;
}
p=p.next;
}
return head;
};
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
var phead=new ListNode(0);
phead.next=head;
var p=phead;
while(p.next!=null)
{
if(p.next.val==val)
{
p.next=p.next.next;
}
else
{
p=p.next;
}
}
return phead.next;
};
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
var newhead=new ListNode();
var p=head,q=head;
while(p!=null)
{
q=q.next;
p.next=newhead.next;
newhead.next=p;
p=q;
}
return newhead.next;
};
var swapPairs = function(head) {
let pre=null,p=head;
let temp;
let counter=0;//计数,偶数换
while(p!=null)
{
counter++;
if(counter%2==0)
{
temp=p.val;
p.val=pre.val;
pre.val=temp;
}
pre=p;
p=p.next;
}
return head;
};
var removeNthFromEnd = function(head, n) {
let vhead=new ListNode(0,head);
let p=head;
let npre,np;//指向p的倒数第n个结点
let counter=0;
while(p!=null)
{
counter++;
p=p.next;
if(counter==n)
{
np=head;
npre=vhead;
}
else if(counter>n)
{
np=np.next;
npre=npre.next;
}
}
// console.log(p);
// console.log(np);
npre.next=np.next;
np.next=null;
//这里注意要return虚拟头结点的next,如果return head 则head要额外处理,而我们增加虚拟头结点的作用就是不额外处理head
return vhead.next;
};
题目链接:面试题 02.07. 链表相交 - 力扣(LeetCode)
//官方解法
var getIntersectionNode = function(headA, headB) {
const visited = new Set();
let temp = headA;
while (temp !== null) {
visited.add(temp);
temp = temp.next;
}
temp = headB;
while (temp !== null) {
if (visited.has(temp)) {
return temp;
}
temp = temp.next;
}
return null;
};
//代码随想录解法
var getLen=function(head)
{
let p=head;
let len=0;
while(p!=null)
{
len++;
p=p.next;
}
return len;
}
var getIntersectionNode = function(headA, headB) {
//当指针相等时即相交
let pA=headA,pB=headB;
//获取两个链表的长度
let lenA=getLen(headA);
let lenB=getLen(headB);
//将两个链表尾部对齐
if(lenA>=lenB)
{
while(lenA!=lenB)
{
pA=pA.next;
lenA--;
}
}
else
{
while(lenA!=lenB)
{
pB=pB.next;
lenB--;
}
}
while(pA!=null)
{
if(pA==pB)
{
return pA;
}
else
{
pA=pA.next;
pB=pB.next;
}
}
return null;
};
//算法思想
//slow和fast从head开始,slow每次走1,fast每次走2,当slow和fast的第一次相遇时说明有环
//(因为fast比slow走得快,所以fast一定先进入环内,走一圈再与slow相遇,所以slow和fast如果相遇说明一定是在环中相遇,一定有环)
//第一次相遇后令slow=head,fast仍在第一次相遇的结点,slow和fast每次都走1,第二次相遇时即环的入口结点
//(因为fast比slow多走n圈,设head到环入口结点的路程为x,环入口结点到slow和fast第一次相遇结点的路程为y,环的路程为R,则slow走的路程为x+y,fast走的路程为x+y+nR,而fast每次走2步,slow每次走1步,他们走的次数是相同的,所以fast的路程是slow的两倍,即x+y+nR=2(x+y),化简得x=nR-y
//当n=1时,x为R-y,即从slow和fast第一次相遇结点开始环剩下的路程。这时令slow=head,fast仍为第一次相遇结点,slow和fast都走1,那么第二次相遇的结点为环入口结点)
var detectCycle = function(head) {
//判断是否有环
let slow=head,fast=head;
while(fast!=null&&fast.next!=null)
{
//slow走1,fast走2
slow=slow.next;
//因为fast.next.next有可能为null所以while中的条件不能单纯为slow和fast!=null
fast=fast.next.next;
//slow和fast第一次相遇
if(slow==fast)
{
//令slow=head,fast仍为第一次相遇的结点
slow=head;
//slow和fast都走1,第二次相遇结点即环入口结点
while(slow!=fast)
{
slow=slow.next;
fast=fast.next;
}
return slow;
}
}
//找不到环入口节点就没有环
return null;
};