代码随想录算法训练营day4|leetcode24 、19、面试题 02.07、142

 24. 两两交换链表中的节点 

题目链接:两两交换链表中的节点

对于这道题,我在写的时候总是报空指针和超时问题,后面才知道在进行节点交换时未保存前一个节点,导致前一个节点成为孤立的节点,无法被访问。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null||head.next==null)
        {
            return head;
        }
        ListNode vhead=new ListNode(0);//创建虚拟头结点
        vhead.next=head;
        ListNode r=vhead;
        while(r.next!=null&&r.next.next!=null)
        {
            ListNode tmp=r.next;//将后面的节点保存
            ListNode tmps=r.next.next.next;//将前面的节点保存
            r.next=r.next.next;
            r.next.next=tmp;
            tmp.next=tmps;
            r=r.next.next;//虚拟头结点要在交换的两个节点的前面一个

        }
        return vhead.next;
    }
}

 19.删除链表的倒数第N个节点

题目链接:删除链表的倒数第N个节点

这道题考的是快慢指针在链表上的运用,快指针与慢指针的距离始终为n(n位倒数第n个节点)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
  if(head==null||head.next==null)
        {
            return null;
        }
        ListNode vhead=new ListNode(0);//创建虚拟头结点
        vhead.next=head;
        ListNode p=vhead;
        ListNode q=vhead;
        for(int i=0;i<n;i++)//快指针移动n步
        {
            q=q.next;
        }
        while(q.next!=null)
        {
            p=p.next;
            q=q.next;
        }
        p.next=p.next.next;
        return vhead.next;
    }
}

 面试题 02.07. 链表相交  

题目链接:链表相交

这道题有着又臭又长的题目描述,其实就是判断两个链表是否相交,相交的条件是是否有一个节点是两个链表共有,且后面的节点与元素也是相同的。

由于两个链表的长度不一样,所以要让出发的节点是一样的。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null)
        {
            return null;
        }
        if(headA.next==null&&headB.next==null&&headA==headB)//只有一个节点,且节点相同
        {
            return headA;
        }
        ListNode p=headA;
        ListNode q=headB;
        int count1=0;
        int count2=0;
//求两个链表的长度
        while(p.next!=null)
        {
            p=p.next;
            count1++;
        }
        while(q.next!=null)
        {
            q=q.next;
            count2++;
        }
        ListNode d1=headA;
        ListNode d2=headB;
//是两个链表在同一起点开始遍历
        if(count1>count2)
        {
            count1=count1-count2;
            for(int i=1;i<=count1;i++)
            {
                d1=d1.next;
            }
        }
        else if(count1<count2)
        {
            count2=count2-count1;
            for(int j=1;j<=count2;j++)
            {
                d2=d2.next;
            }
        }
//判断链表是否存在相同节点
        while(d1!=null&&d2!=null)//使其能遍历到链表的最后一个节点,
        {
            if(d1==d2)
            {
                return d1;
            }
            d1=d1.next;
            d2=d2.next;
        }
        return null;
    }
}

 142.环形链表II  

题目链接:环形链表II

这道题考的是环形链表,主要看的是两个点:1.判断链表是否为环形链表;2.找出进入环形链表的首节点。这道题可以用快慢指针来判断是否存在环形链表,如果环形链表存在,快慢指针会在环形链表的某处重合

 由上图可知快指针在环形链表内走的长度为:n(y+z)

慢指针走到相遇点的长度为x+y

故:x+y=n(y+z)  可得: x=(n-1)(y+z)+z

所以快指针在环形链表内走了(n-1)圈后到快慢指针相遇点,再走长度z可与从开始走长度为x的指针相遇

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null||head.next==null)
        {
            return null;
        }
        ListNode p=head;//slow
        ListNode q=head; //fast
        ListNode cur=head;
//判断是否为环形链表
        while(q!=null&&q.next!=null)
        {
            p=p.next;
            q=q.next.next;
            if(p==q)
            {
                break;
            }
        }
        if(q==null||q.next==null)
        {
            return null;
        }
//判断是否相遇,相遇的点就为换开始的第1个节点
        ListNode idx=q;
        while(idx!=cur)
        {
            cur=cur.next;
            idx=idx.next;
        }
        return cur;
        
    }
}

总结:对于今天的题目,主要是考验我对于链表的掌握,虽然被空指针搞爆了心态,今后对于链表还是要理清是否会产生空指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值