数据结构之链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */

 

移除链表元素  题目  解析

用虚节点放在head前面,可以让head的删除不必单独分析。

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode virHead = new ListNode();
        virHead.next = head;
        ListNode cur = virHead;
        while (cur.next != null) {
            if (cur.next.val == val) {
                cur.next = cur.next.next;
            }
            else {
                cur = cur.next;
            }
        }
        return virHead.next;
    }
}

 

反转链表  题目  解析

逆转除了双指针和递归,还可以用栈(单纯打印逆转数据)。

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode temp = new ListNode();
        ListNode pre = null;
        ListNode cur = head;
        while(cur != null) {     //结束时是cur为null,pre为原链表尾部
            temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

 

相交链表  题目  解析

看作A和B都要走完两段路,如果有交点。因为总路程一样,相遇后的路程一样,所以相遇即相交。

如果A和B没有交点,即后来都到达了null。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode preA = headA;
        ListNode preB = headB;
        while (preA != preB) { 
            preA = preA == null ? headB : preA.next;
            preB = preB == null ? headA : preB.next;
        }
        return preA;
    }
}

 

合并两个有序链表 题目 解析

迭代都会写,递归一看就会一写就废

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

 

删除排序链表中的重复元素 题目 解析

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode p = head;
        while(p != null && p.next != null) {
            if (p.val == p.next.val) {
               p.next = p.next.next;
            } else {
            p = p.next;
            }
        }
        return head;
    }
}

 

删除链表的倒数第N个节点 题目 解析

快慢指针找位置,虚头节点删除。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode prehead = new ListNode();
        prehead.next = head;
        ListNode r = prehead;
        ListNode l = prehead;
        for (int i = 0; i < n; i++) {
            r = r.next;
        }
        while (r != null && r.next != null) {
            r = r.next;
            l = l.next;
        }
        l.next = l.next.next;
        return prehead.next;
    }
}

 

两两交换链表 题目 解析

虽然我是一个只会用迭代的fw,但是我还是要把递归放上去。解析是递归(强烈建议看一看解析)。

class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode newhead = head.next;
        head.next = swapPairs(newhead.next);
        newhead.next = head;
        return newhead;
    }
}

 

链表求和 题目 解析

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        LinkedList<Integer> stack1 = new LinkedList<>();
        LinkedList<Integer> stack2 = new LinkedList<>();
        while (l1 != null) {
            stack1.addLast(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            stack2.addLast(l2.val);
            l2 = l2.next;
        }
        int count = 0;
        ListNode head = null;
        while (!stack1.isEmpty() || !stack2.isEmpty() || count != 0) {
            int n1 = !stack1.isEmpty() ? stack1.removeLast() : 0;
            int n2 = !stack2.isEmpty() ? stack2.removeLast() : 0;
            int val = (n1 + n2 + count) % 10;
            count = (n1 + n2 + count) / 10;
            ListNode temp = head;
            head = new ListNode(val);
            head.next = temp;
        }
        return head;
    }
}

 

 

 

回文链表 题目

 

分隔链表 题目

 

奇偶链表 题目

 一开始用奇链表当判断条件,结果还要分情况考虑。既然偶链表是加在后面的,循环时就根据偶链表来判断比较好哇。

class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null) return head;
        ListNode even = head.next;
        ListNode tempeven = even;
        ListNode temphead = head;
        while (tempeven != null && tempeven.next != null) {
            temphead.next = temphead.next.next;
            temphead = temphead.next;
            tempeven.next = tempeven.next.next;
            tempeven = tempeven.next;
        }
        temphead.next = even;
        return head;
    }
}

 

旋转链表 题目 解析

构成一个环,再跑。

class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null || head.next == null) return head;
        int n = 1;
        ListNode tail = head;
        while (tail.next != null) {
            tail = tail.next;
            n++;
        }
        tail.next = head;
        for (int i = 0; i < n - (k % n); i++) {
            head = head.next;
            tail = tail.next;
        }
        tail.next = null;
        return head;
    }
}

 

posted @ 2020-11-04 00:01  CPJ31415  阅读(72)  评论(0)    收藏  举报