LeetCode解題(20200629)——鏈表題目集合

Leetcode中的常見的鏈表操作題目:

2. 兩數相加

/**
 * Copyright (C), 2018-2020
 * FileName: addTwoNumbers2
 * Author:   xjl
 * Date:     2020/7/1 14:02
 * Description: 兩個鏈表,代表兩個整數的逆序,返回一個鏈表,代表兩個整數相加和的逆序。
 */
package LinkList;

import org.junit.Test;

/**
 * leetcode 的兩個鏈表的相加
 * (2 -> 4 -> 3) + (5 -> 6 -> 4)
 * Output: 7 -> 0 -> 8
 */
public class addTwoNumbers2 {
    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    /**
     * 兩個鏈表的相加
     */
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode s1 = l1;
        ListNode s2 = l2;

        ListNode node = new ListNode(0);
        ListNode result = node;
        int curr = 0;

        while (s1 != null || s2 != null) {
            int a = s1 != null ? s1.val : 0;
            int b = s2 != null ? s2.val : 0;
            int sum = a + b + curr;
            int val = sum % 10;
            curr = sum / 10;
            result.next = new ListNode(val);
            result = result.next;

            if (s1 != null) {
                s1 = s1.next;
            }
            if (s2 != null) {
                s2 = s2.next;
            }
        }
        if (curr == 1) {
            result.next = new ListNode(curr);
        }
        return node.next;
    }

    @Test
    public void test() {
        ListNode s1 = new ListNode(2);
        ListNode s2 = new ListNode(4);
        ListNode s3 = new ListNode(3);

        ListNode s5 = new ListNode(5);
        ListNode s6 = new ListNode(6);
        ListNode s7 = new ListNode(4);

        s1.next = s2;
        s2.next = s3;

        s5.next = s6;
        s6.next = s7;

        ListNode listNode = addTwoNumbers(s1, s5);

        while (listNode != null) {
            System.out.print(listNode.val);
            listNode = listNode.next;
        }
    }

}

19. 刪除鏈表的倒數第N個節點

/**
 * Copyright (C), 2018-2020
 * FileName: removeNthFromEnd19
 * Author:   xjl
 * Date:     2020/7/1 14:45
 * Description: 19. 刪除鏈表的倒數第N個節點
 */
package LinkList;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class removeNthFromEnd19 {
    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    public ListNode removeNthFromEnd(ListNode head, int n) {
        //1將鏈表反轉 後倆刪除這個節點

        //2 利用的是list的集合刪除後在將鏈表重建
        List<Integer> list = new ArrayList<>();
        while (head != null) {
            list.add(head.val);
            head = head.next;
        }
        int index = list.size() - n;
        int i = 0;
        ListNode curr = new ListNode(0);
        ListNode res = curr;
        for (int val : list) {
            if (i++ == index) {
                continue;
            }
            res.next = new ListNode(val);
            res = res.next;
        }
        //3 先遍歷在實現這個東西
        return curr.next;
    }

    /**
     * 採用的是雙指針
     *
     * @param head
     * @param n
     * @return
     */
    public ListNode removeNthFromEnd2(ListNode head, int n) {
        ListNode frist = head;
        for (int i = 0; i < n; i++) {
            frist = frist.next;
        }
        if (frist == null) {
            return head.next;
        }
        ListNode second = head;
        while (frist.next != null) {
            frist = frist.next;
            second = second.next;
        }
        second.next = second.next.next;
        return head;
    }

    @Test
    public void test() {
        ListNode s1 = new ListNode(1);
        ListNode s2 = new ListNode(2);
        ListNode s3 = new ListNode(3);
        ListNode s4 = new ListNode(4);
        ListNode s5 = new ListNode(5);
        ListNode s6 = new ListNode(6);

        s1.next = s2;
        s2.next = s3;
        s3.next = s4;
        s4.next = s5;
        s5.next = s6;

        ListNode listNode = removeNthFromEnd2(s1, 2);

        while (listNode != null) {
            System.out.print(listNode.val);
            listNode = listNode.next;
        }
    }
}

21. 合併兩個有序鏈表

/**
 * Copyright (C), 2018-2020
 * FileName: mergeTwoLists21
 * Author:   xjl
 * Date:     2020/7/1 14:17
 * Description: 兩個有序鏈表的合併
 */
package LinkList;

public class mergeTwoLists21 {

    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        // 創建一個新的鏈表
        ListNode pre = new ListNode(0);
        ListNode cur = pre;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                cur.next = l1;
                cur = cur.next;
                l1 = l1.next;
            } else {
                cur.next = l2;
                cur = cur.next;
                l2 = l2.next;
            }
        }
        // 任一爲空,直接連接另一條鏈表
        if (l1 == null) {
            cur.next = l2;
        } else {
            cur.next = l1;
        }
        return pre.next;
    }
    
}

141. 環形鏈表

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) {
            return false;
        }
        ListNode curr = head;
        ListNode low = curr;
        ListNode fast = curr.next;
        while (low != fast) {
            //如果是沒有環的話則返回flase
            if (fast == null || fast.next == null) {
                return false;
            }
            low = low.next;
            fast = fast.next.next;
        }
        return true; 
    }
}

206. 反轉鏈表

class Solution {
    public ListNode reverseList(ListNode head) {
        //定義一個空節點 用於來做空節點
        ListNode pre=null;
        //定義一個當前遍歷的節點
        ListNode curr=head;
        while(curr!=null){
            ListNode next=curr.next;
            curr.next=pre;
            pre=curr;
            curr=next;
        }
        return pre;
    }
}

鏈表的中間結點(leetcode 876)

    public ListNode middleNode(ListNode head) {
        ListNode a = head;
        ListNode b = head;
        while (a != null && a.next != null) {
            a = a.next.next;
            b = b.next;
        }
        return b;
    }

203. 移除鏈表元素

 public ListNode removeElements(ListNode head, int val) {
        ListNode node = new ListNode(0);
        node.next = head;

        ListNode prev = node;
        ListNode curr = head;

        while (curr != null) {
            if (curr.val == val) {
                prev.next = curr.next;
            } else {
                prev = curr;
            }
            curr=curr.next;
        }
        return node.next;
    }

147. 對鏈表進行插入排序

/**
 * Copyright (C), 2018-2020
 * FileName: insertionSortList147
 * Author:   xjl
 * Date:     2020/6/29 10:13
 * Description: 147. 對鏈表進行插入排序
 */
package LinkList;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;

public class insertionSortList147 {
    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    public ListNode insertionSortList(ListNode head) {
        ArrayList<Integer> list = new ArrayList();
        ListNode res = new ListNode(0);
        ListNode pre=res;

        ListNode curr = head;
        while (curr != null) {
            list.add(curr.val);
            curr = curr.next;
        }
        Collections.sort(list);
        for (int V : list) {
            pre.next = new ListNode(V);
            pre = pre.next;
        }
        return res.next;
    }

    @Test
    public void test() {
        ListNode s1 = new ListNode(1);
        ListNode s2 = new ListNode(2);
        ListNode s3 = new ListNode(6);
        ListNode s4 = new ListNode(3);
        ListNode s5 = new ListNode(4);
        ListNode s6 = new ListNode(5);
        ListNode s7 = new ListNode(1);

        s1.next = s2;
        s2.next = s3;
        s3.next = s4;
        s4.next = s5;
        s5.next = s6;
        s6.next = s7;

        ListNode node = insertionSortList(s1);
        while (node != null) {
            System.out.print(node.val + " ");
            node = node.next;
        }
    }
}

237. 刪除鏈表中的節點

 

83. 刪除排序鏈表中的重複元素

class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode node = new ListNode(0);
        node.next = head;
        ListNode pre = node;
        ListNode curr = head;
        while (curr!= null) {
            while (curr.next!=null&&curr.val == curr.next.val) {
                curr = curr.next;
            }
            pre.next = curr;
            pre = pre.next;
            curr = curr.next;
        }
        return node.next;
    }
}

1047. 刪除字符串中的所有相鄰重複項

/**
 * Copyright (C), 2018-2020
 * FileName: removeDuplicates1047
 * Author:   xjl
 * Date:     2020/6/29 10:46
 * Description: 1047. 刪除字符串中的所有相鄰重複項
 */
package String;

import org.junit.Test;

public class removeDuplicates1047 {
    public String removeDuplicates(String S) {
        StringBuilder sb = new StringBuilder();
        int sbLength = 0;
        for (char character : S.toCharArray()) {
            if (sbLength != 0 && character == sb.charAt(sbLength - 1))
                sb.deleteCharAt(sbLength-- - 1);
            else {
                sb.append(character);
                sbLength++;
            }
        }
        return sb.toString();
    }

    @Test
    public void test() {
        String res = removeDuplicates("abbaca");
        System.out.println(res);

    }
}

82. 刪除排序鏈表中的重複元素 II

/**
 * Copyright (C), 2018-2020
 * FileName: deleteDuplicates82
 * Author:   xjl
 * Date:     2020/6/29 11:09
 * Description: 82. 刪除排序鏈表中的重複元素 II
 */
package LinkList;

import org.junit.Test;

public class deleteDuplicates82 {

    public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    public ListNode deleteDuplicates(ListNode head) {
        ListNode node = new ListNode(0);
        node.next = head;
        ListNode pre = node;
        ListNode curr = head;
        while (curr != null) {
            if (curr.next != null && curr.val == curr.next.val) {
                while (curr.next != null && curr.val == curr.next.val) {
                    curr = curr.next;
                }
                curr = curr.next;
                pre.next = curr;
            } else {
                pre = pre.next;
                curr = curr.next;
            }
        }
        return node.next;
    }

    @Test
    public void test() {
        ListNode s1 = new ListNode(1);
        ListNode s2 = new ListNode(1);
        ListNode s3 = new ListNode(1);
        ListNode s4 = new ListNode(3);
        ListNode s5 = new ListNode(3);
        ListNode s6 = new ListNode(5);
        ListNode s7 = new ListNode(1);

        s1.next = s2;
        s2.next = s3;
        s3.next = s4;
        s4.next = s5;
        s5.next = s6;
        s6.next = s7;

        ListNode listNode = deleteDuplicates(null);
        while (listNode != null) {
            System.out.print(listNode.val + " ");
            listNode = listNode.next;
        }
    }
}

80. 刪除排序數組中的重複項 II

No.24 Swap Nodes in Pairs(兩兩交換鏈表中的節點)
No.86 Partition List(分隔鏈表)
No.92 Reverse Linked List II(倒置鏈表Ⅱ)
No.160 Intersection of Two Linked Lists(相交鏈表)
No.234 Palindrome Linked List(迴文鏈表)
No.237 Delete Node in a Linked List (刪除鏈表中的節點)
No.328 Odd Even Linked List(奇偶鏈表)
No.445 Add Two Numbers II(兩數相加Ⅱ)
No.817 Linked List Components(鏈表組件)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章