代码随想录第四天:24.两两交换列表中的结点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

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 dummy = new ListNode(0,head);
        ListNode p = dummy, left = head, right = left.next;
        while(left!=null){
            p.next = right;
            left.next = right.next;
            right.next = left;

            p = left;
            left = left.next;
            if(left==null)
                break;
            right = left.next;
            if(right == null){
                break;
            }
        }
        return dummy.next;
    }
}

 19:删除链表中的倒数第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)
            return null;
        int size = 0;
        ListNode dummy = new ListNode(0,head);
        ListNode p = head;
        while(p!=null){
            p=p.next;
            size++;
        }
        int k = size - n;
        int i;
        for(p=dummy,i=0;i<size;i++,p=p.next){
            if(i==k){
                p.next = p.next.next;
            }
        }
        return dummy.next;
    }
}

双指针法:利用快慢指针进行遍历,定义slow和fast指针都指向head结点,快指针前进N+1个结点,然后slow和fast指针每次向前移动一个结点,如果fast指针指向为null,则说明到了结尾,slow指针的下一个结点就是倒数第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)
            return null;
        ListNode dummy = new ListNode(0,head);
        ListNode slow = dummy, fast = dummy;
        for(int i=0;i<=n;i++)
            fast = fast.next;
        while(fast!=null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return dummy.next;
    }
}

面试题 02.07:链表相交

如果headA长于headB,curA指向headA,curB指向headB,移动curA使得curA和curB长度一致,之后curA和curB依次向前移动,如果curA和curB指向同一个结点,说明这个结点就是相交结点。

/**
 * 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) {
        int sizeA = 0;
        int sizeB = 0;
        for(ListNode p=headA;p!=null;p=p.next)
            sizeA++;
        for(ListNode p=headB;p!=null;p=p.next)
            sizeB++;  
        int d = sizeA > sizeB ? sizeA - sizeB : sizeB - sizeA;
        ListNode curA = headA, curB = headB;
        if(sizeA > sizeB){
            for(int i=0;i<d;i++){
                curA = curA.next;
            }
        }else if(sizeA < sizeB){
            for(int i=0;i<d;i++){
                curB = curB.next;
            }
        }

        while(curA!=null){
            if(curA == curB){
                return curA;
            }else{
                curA = curA.next;
                curB = curB.next;
            }
        }
        return null;
    }
}

9:环形列表II

参考Carl哥的题解,思路还是很清楚的,很有收获。

/**
 * 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)    return null;
        ListNode fast = head, slow = head;
        while((fast!=null)&&(fast.next!=null)){
            slow = slow.next;
            fast = fast.next.next;
            if(fast == slow){
                ListNode curA = head, curB = slow;
                while(curA!=curB){
                    curA = curA.next;
                    curB = curB.next;
                }
                return curA;
            }
        }
        return null;
    }
}

总结:经过这段时间,对链表的操作方式和双指针方法熟练了很多,找到思路的话代码实现速度也快了不少。希望能坚持下去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值