【LeetCode】初级算法:链表

题目可以在LeetCode查看

1. 删除链表的结点

用时:0ms

class Solution {
    public void deleteNode(ListNode node) {
        node.val=node.next.val;
        node.next=node.next.next;
    }
}

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

用时:10ms

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode curNode=head;
        ListNode nNode=head;
        int count=1;
        while(curNode.next!=null){
            // 如果删除末尾结点,则判断当前结点是否是倒数第二个结点
            if(n==1&&curNode.next.next==null){
                curNode.next=null;
                return head;
            }
            // 如果和当前结点中间的结点数为n,则移动nNode
            if(count==n){
                nNode=nNode.next;
            }else{
                ++count;
            }
            curNode=curNode.next;
        }
        // 如果只有一个结点
        if(nNode==head&&n==1){
            return null;
        }
        // 删除该结点
        nNode.val=nNode.next.val;
        nNode.next=nNode.next.next;
        return head;
    }
}

3. 反转链表

用时:0ms

class Solution {
    public ListNode reverseList(ListNode head) {
        // 用时:0ms
        // // 如果是空链表或者单结点则直接返回
        // if(head==null||head.next==null){
        //     return head;
        // }
        // // 反转框包含三个结点
        // ListNode pre=null;
        // ListNode cur=head;
        // ListNode nxt=head.next;
        // while(true){
        //     // 反转结点
        //     cur.next=pre;
        //     pre=nxt.next;
        //     nxt.next=cur;
        //     // 如果当前反转框是最后一个
        //     if(pre==null){
        //         return nxt;
        //     }
        //     // 移动反转框
        //     cur=pre.next;
        //     // 连接上一个反转框的nextNode
        //     pre.next=nxt;
        //     // 如果下个反转框为一个结点
        //     if(cur==null){
        //         return pre;
        //     }
        //     // 如果下个反转组为两个结点
        //     if(cur.next==null){
        //         cur.next=pre;
        //         return cur;
        //     }
        //     // 否则继续移动反转框
        //     nxt=cur.next;
        // }
        
        // 如果是空链表或者单结点则直接返回
        if(head==null||head.next==null){
            return head;
        }
        return recursive(null,head,head.next);
    }
    
    public ListNode recursive(ListNode pre,ListNode cur,ListNode nxt){
        // 反转结点
        cur.next=pre;
        pre=nxt.next;
        nxt.next=cur;
        // 如果当前反转框是最后一个
        if(pre==null){
            return nxt;
        }
        // 移动反转框
        cur=pre.next;
        // 连接上一个反转框的nextNode
        pre.next=nxt;
        // 如果下个反转框为一个结点
        if(cur==null){
            return pre;
        }
        // 如果下个反转组为两个结点
        if(cur.next==null){
            cur.next=pre;
            return cur;
        }
        // 否则继续移动反转框
        nxt=cur.next;
        return recursive(pre,cur,nxt);
    }
}

4. 合并两个有序链表

用时:12ms

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode newHead=null;
        ListNode newPre=null;
        ListNode newCur=null;
        // 如果有一个链表为空,则返回另一个
        if(l1==null){
            return l2;
        }else if(l2==null){
            return l1;
        }
        // 先将两者之间较小的合并
        while(l1!=null&&l2!=null){
            if(l1.val>=l2.val){
                newCur=new ListNode(l2.val);
                l2=l2.next;
            }else{
                newCur=new ListNode(l1.val);
                l1=l1.next;
            }
            // 保存头结点
            if(newHead==null){
                newHead=newCur;
            }
            if(newPre!=null){
                newPre.next=newCur;
            }
            newPre=newCur;
        }
        
        // 再将剩下的合并
        while(l1!=null){
            newCur=new ListNode(l1.val);
            newPre.next=newCur;
            newPre=newPre.next;
            l1=l1.next;
        }
        while(l2!=null){
            newCur=new ListNode(l2.val);
            newPre.next=newCur;
            newPre=newPre.next;
            l2=l2.next;
        }
        
        return newHead;
    }
}

5. 回文链表

用时:2ms

class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        int len=0;
        ListNode curNode=head;
        // 计算链表长度
        while(curNode!=null){
            ++len;
            curNode=curNode.next;
        }
        // 找到中间结点
        ListNode cntNode=head;
        for(int i=1;i

6. 环形链表

用时:1ms

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow=head;
        ListNode fast=head;
        // 快慢车问题,快的总会追上慢的
        while(fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast){
                return true;
            }
        }
        return false;
    }
}

你可能感兴趣的:(OJcode,LeetCode)