leetcode 链表题总结

按照frequency来排序,总共27题

1、2. Add Two Numbers  https://leetcode.com/problems/add-two-numbers/#/description

两个链表相加,注意就是进位问题。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int flag = 0;
        ListNode result = new ListNode(0);
        ListNode node = result;
        while (l1 != null || l2 != null){
            int val = flag;
            if (l1 != null){
                val += l1.val;
                l1 = l1.next;
            }
            if (l2 != null){
                val += l2.val;
                l2 = l2.next;
            }
            if (val > 9){
                val -= 10;
                flag = 1;
            } else {
                flag = 0;
            }
            node.next = new ListNode(val);
            node = node.next;
        }
        if (flag == 1){
            node.next = new ListNode(1);
        }
        return result.next;
    }
}

2、237. Delete Node in a Linked List  https://leetcode.com/problems/delete-node-in-a-linked-list/#/description

删除链表中的节点。只给需要删除的节点。很简单,两行代码就搞定了。

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

3、206. Reverse Linked List  https://leetcode.com/problems/reverse-linked-list/#/description

反转链表。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null){
            return head;
        }
        ListNode pre = head;
        ListNode node = head.next;
        head.next = null;
        while (node.next != null){
            ListNode flag = node.next;
            node.next = head;
            head = node;
            node = flag;
        }
        node.next = head;
        return node;
    }
}

4、148. Sort List  https://leetcode.com/problems/sort-list/#/description

链表排序。要求nlogn的时间复杂度和常数的空间复杂度。那么应用归并排序。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null){
            return head;
        }
        ListNode pre = null;
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null){
            pre = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        pre.next = null;
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(slow);

        return sortList(l1, l2);

    }
    public ListNode sortList(ListNode node1, ListNode node2){
        ListNode node = new ListNode(0);
        ListNode nn = node;
        while (node1 != null && node2 != null){
            if (node1.val < node2.val){
                nn.next = node1;
                node1 = node1.next;
            } else {
                nn.next = node2;
                node2 = node2.next;
            }
            nn = nn.next;
        }
        while (node1 != null){
            nn.next = node1;
            nn = nn.next;
            node1 = node1.next;
        }
        while (node2 != null){
            nn.next = node2;
            nn = nn.next;
            node2 = node2.next;
        }
        return node.next;
    }
}

5、141. Linked List Cycle    https://leetcode.com/problems/linked-list-cycle/#/description

判断链表是否有环。

一个快,一个慢,判断是否会走到一起(如果成环一定可以走到一起)。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null){
            return false;
        }
        ListNode slow = head.next;
        ListNode fast = head.next.next;
        while (fast != null && fast.next != null && slow != fast){
            fast = fast.next.next;
            slow = slow.next;
        }
        return (fast == null || fast.next == null) ? false : true;
    }
}

6、328. Odd Even Linked List    https://leetcode.com/problems/odd-even-linked-list/#/description

将链表分为偶数和奇数两块,奇数放在前面,偶数放在后面。

刚开始看错题目,说的是将第偶数个放在一起,第奇数个放在一起,并非链表中的数值。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null || head.next == null){
            return head;
        }
        ListNode odd = head, even = head.next, evenhead = even;
        while (even != null && even.next != null){
            odd.next = odd.next.next;
            even.next = even.next.next;
            odd = odd.next;
            even = even.next;
        }
        odd.next = evenhead;
        return head;
    }
}

7、21. Merge Two Sorted Lists  链表合并  https://leetcode.com/problems/merge-two-sorted-lists/#

简单的两路归并。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode head = new ListNode(0), node = head;;
        while (l1 != null && l2 != null){
            if (l1.val > l2.val){
                node.next = l2;
                l2 = l2.next;
            } else {
                node.next = l1;
                l1 = l1.next;
            }
            node = node.next;
        }
        if (l1 != null){
            node.next = l1;
        } else if (l2 != null){
            node.next = l2;
        }
        return head.next;
    }
}

8、160. Intersection of Two Linked Lists返回两个链表的第一个交点。  https://leetcode.com/problems/intersection-of-two-linked-lists/#/description

a、找出长度差,然后长的链表先行长度差个,然后依次比较,找出交点(没有就是null)。

b、用hash

/**
 * 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 len1 = 0, len2 = 0;
        ListNode node = headA;
        while (node != null){
            node = node.next;
            len1++;
        }
        node = headB;
        while (node != null){
            node = node.next;
            len2++;
        }
        if (len1 > len2){
            for (int i = 0; i < len1 - len2; i++){
                headA = headA.next;
            }
        } else {
            for (int i = 0; i < len2 - len1; i++){
                headB = headB.next;
            }
        }
        while (headA != headB){
            headA = headA.next;
            headB = headB.next;
        }
        return headA;
    }
}

另外,可以这样解。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    //boundary check
    if(headA == null || headB == null) return null;

    ListNode a = headA;
    ListNode b = headB;

    //if a & b have different len, then we will stop the loop after second iteration
    while( a != b){
        //for the end of first iteration, we just reset the pointer to the head of another linkedlist
        a = a == null? headB : a.next;
        b = b == null? headA : b.next;
    }

    return a;
}

9、138. Copy List with Random Pointer 拷贝随机链表  https://leetcode.com/problems/copy-list-with-random-pointer/#/description

a、hash

b、在每一个链表后面添加一个链表。

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    public RandomListNode copyRandomList(RandomListNode head) {
        if (head == null){
            return null;
        }
        RandomListNode node = head, next;
        while (node != null){
            next = node.next;
            node.next = new RandomListNode(node.label);
            node.next.next = next;
            node = next;
        }
        node = head;
        while (node != null){
            if (node.random != null){
                node.next.random = node.random.next;
            }
            node = node.next.next;
        }
        RandomListNode newHead = new RandomListNode(0), result = newHead;
        node = head;
        while (node != null){
            next = node.next.next;
            newHead.next = node.next;
            newHead = newHead.next;
            node.next = next;
            node = node.next;
        }
        return result.next;
    }
}

10、23. Merge k Sorted Lists  k个链表的合并。    https://leetcode.com/problems/merge-k-sorted-lists/#/description

k路归并,利用优先级队列PriorityQueue

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        ListNode head = new ListNode(0), node = head;
        int size = lists.length;
        if (size == 0){
            return null;
        }
        Comparator<ListNode> comparator = new Comparator<ListNode>(){
          public int compare(ListNode o1, ListNode o2){
              if (o1.val > o2.val){
                  return 1;
              } else if (o1.val < o2.val){
                  return -1;
              } else {
                  return 0;
              }
          }
        };
        PriorityQueue<ListNode> queue = new PriorityQueue(size, comparator);
        for (int i = 0; i < size; i++){
            if (lists[i] != null)
                queue.add(lists[i]);
        }
        while (!queue.isEmpty()){
            node.next = queue.poll();
            node = node.next;
            if (node.next != null){
                queue.add(node.next);
            }
        }
        return head.next;
    }
}

11、234. Palindrome Linked List  判断是否是回文链表  https://leetcode.com/problems/palindrome-linked-list/#/solutions

(123,123)是回文,(123,321)不是。  

由于没有时间了,写上思路:a、利用栈,时间O(n),空间O(N);

             b、找到中点(fast、slow一快一慢来判断),后半部分反转。然后判断。

12、147. Insertion Sort List  链表插入排序  https://leetcode.com/problems/insertion-sort-list/#/description

没什么技巧和难点。

13、142. Linked List Cycle II  找出链表循环的起点  https://leetcode.com/problems/linked-list-cycle-ii/#/description

与第五题也就是141相同,相遇的点就是循环的起点(数学方法证明)。

14、19. Remove Nth Node From End of List  删除倒数第n个节点    https://leetcode.com/problems/remove-nth-node-from-end-of-list/#/description

fast先走n个节点,然后slow再走,直到 fast == null为止,跳过slow.next即可。

这里需要了解n的范围,会不会超过长度,如果超过了长度要怎么办。

15、143. Reorder List  将链表按照固定方式改写。    https://leetcode.com/problems/reorder-list/#/description

Given a singly linked list LL0→L1→…→Ln-1→Ln,
reorder it to: L0→LnL1→Ln-1→L2→Ln-2→…

1、用list或者数组记录

2、用双向队列(Deque)

3、链表分成两半,然后后一半反转,然后合并两个链表。

16、24. Swap Nodes in Pairs  节点两两交换    https://leetcode.com/problems/swap-nodes-in-pairs/#/description

a、递归实现

b、非递归

17、203. Remove Linked List Elements  删除某个值    https://leetcode.com/problems/remove-linked-list-elements/#/description

遍历直接删除就行了

18、83. Remove Duplicates from Sorted List  删除重复的数    https://leetcode.com/problems/remove-duplicates-from-sorted-list/#/description

也是递归、非递归实现。

19、109. Convert Sorted List to Binary Search Tree  排序好的链表建树    https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/#/description

递归实现,二分查找。

20、92. Reverse Linked List II   链表的部分反转    https://leetcode.com/problems/reverse-linked-list-ii/#/description

21、86. Partition List   划分链表的值    https://leetcode.com/problems/partition-list/#/description

给定一个值,把小于x的值放在左边,大于等于x的值放在右边,保持相对顺序。

没什么难点。

22、25. Reverse Nodes in k-Group    部分反转    https://leetcode.com/problems/reverse-nodes-in-k-group/#/description

也是递归和非递归的实现。

23、61. Rotate List    旋转链表    https://leetcode.com/problems/rotate-list/#/description

从倒数第k个位置开始旋转一下链表。

需要判断k是否大于len。

24、82. Remove Duplicates from Sorted List II    去掉重复的数字(一个都不留)    https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/#/description

没什么难点。遍历一次就行了

25、445. Add Two Numbers II    链表相加(与之前一体的区别是反过来了,而且不允许反转链表)

1、首先想到的应该是反转链表,然后求出答案,这样空间复杂度是O(n);

2、借助辅助空间,stack。

3、日常递归实现。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<Integer> l1_stack = new Stack();
        Stack<Integer> l2_stack = new Stack();
        while (l1 != null){
            l1_stack.add(l1.val);
            l1 = l1.next;
        }
        while (l2 != null){
            l2_stack.add(l2.val);
            l2 = l2.next;
        }
        ListNode head = new ListNode(0), curr = null;
        int flag = 0;
        while (!l1_stack.isEmpty() || !l2_stack.isEmpty() || flag == 1){
            int num = flag;
            if (!l1_stack.isEmpty()){
                num += l1_stack.pop();
            }
            if (!l2_stack.isEmpty()){
                num += l2_stack.pop();
            }
            if (num > 9){
                num -= 10;
                flag = 1;
            } else {
                flag = 0;
            }
            ListNode node = new ListNode(num);
            node.next = curr;
            curr = node;
            head.next = node;
        }
        return head.next;
    }
}
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int len1 = getLen(l1);
        int len2 = getLen(l2);
        ListNode head = new ListNode(1);
        head.next = len1 > len2 ? helper(l1, l2, len1 - len2) : helper(l2, l1, len2 - len1);
        if (head.next.val > 9){
            head.next.val -= 10;
            return head;
        }
        return head.next;
    }

    public ListNode helper(ListNode l1, ListNode l2, int offset){
        if (l1 == null){
            return null;
        }
        ListNode node = offset == 0 ? new ListNode(l1.val + l2.val) : new ListNode(l1.val);
        ListNode next = offset == 0 ? helper(l1.next, l2.next, 0) : helper(l1.next, l2, offset - 1);

        if (next != null && next.val > 9){
            next.val -= 10;
            node.val += 1;
        }
        node.next = next;

        return node;
    }

    public int getLen(ListNode node){
        int len = 0;
        while (node != null){
            node = node.next;
            len++;
        }
        return len;
    }
}

26、379. Design Phone Directory  设计电话字典。设计题。并不知道哪里用到了链表。    https://leetcode.com/problems/design-phone-directory/#/description

a、直接用数组就可以实现。

b、用队列 + set可以实现(更快一些,数组每次get需要遍历)。

这里用了数组实现。

public class PhoneDirectory {

    /** Initialize your data structure here
        @param maxNumbers - The maximum numbers that can be stored in the phone directory. */
    private int[] phone;
    public PhoneDirectory(int maxNumbers) {
        phone = new int[maxNumbers];
        for (int i = 0; i < maxNumbers; i++){
            phone[i] = 1;
        }
    }

    /** Provide a number which is not assigned to anyone.
        @return - Return an available number. Return -1 if none is available. */
    public int get() {
        for (int i = 0; i < phone.length; i++){
            if (phone[i] == 1){
                phone[i] = 0;
                return i;
            }
        }
        return -1;
    }

    /** Check if a number is available or not. */
    public boolean check(int number) {
        if (number < 0 || number > phone.length){
            return false;
        }
        return phone[number] == 1;
    }

    /** Recycle or release a number. */
    public void release(int number) {
        phone[number] = 1;
    }
}

/**
 * Your PhoneDirectory object will be instantiated and called as such:
 * PhoneDirectory obj = new PhoneDirectory(maxNumbers);
 * int param_1 = obj.get();
 * boolean param_2 = obj.check(number);
 * obj.release(number);
 */

27、369. Plus One Linked List  链表+1    https://leetcode.com/problems/plus-one-linked-list/#/description

1、递归。、

2、判断末尾有多少个连续的9即可。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode plusOne(ListNode head) {
        ListNode node = new ListNode(1);
        node.next = head;
        plusOneHelper(head);
        if (node.next.val > 9){
            node.next.val -= 10;
            return node;
        }
        return node.next;
    }

    public void plusOneHelper(ListNode node){
        if (node.next == null){
            node.val += 1;
            return ;
        } else {
            plusOneHelper(node.next);
            if (node.next.val > 9){
                node.next.val -= 10;
                node.val += 1;
            }
        }
        return ;
    }

}
时间: 2024-10-14 11:02:32

leetcode 链表题总结的相关文章

LeetCode 链表题 ( Java )

leetcode 237. 删除链表中的节点 链接:https://leetcode-cn.com/problems/delete-node-in-a-linked-list/ 示例 : 输入: head = [4,5,1,9], node = 5输出: [4,1,9]解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 这道题比较简单,修改之前节点的 next 指针,使其指向之后的节点: /** * Definition for sin

LeetCode刷题总结-链表

LeetCode刷题总结-链表 一.链表     链表分为单向链表.单向循环链表和双向链表,一下以单向链表为例实现单向链表的节点实现和单链表的基本操作. 单向链表 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 表元素域elem用来存放具体的数据: 链接域next用来存放下一个节点的位置(python中的标识): 变量p指向链表的头节点(首节点)的位置,从p出发能找到表

[Leetcode]leetcode1-10题随记

因为leetcode的题号会变动,所以先记录一下每一题对应的内容.   10 Regular Expression Matching 21.6% Hard   9 Palindrome Number 30.9% Easy   8 String to Integer (atoi) 13.3% Easy   7 Reverse Integer 23.6% Easy   6 ZigZag Conversion 23.3% Easy   5 Longest Palindromic Substring 2

【leetcode刷题笔记】Insertion Sort List

Sort a linked list using insertion sort. 题解:实现链表的插入排序. 要注意的地方就是,处理链表插入的时候尽量往当前游标的后面插入,而不要往前面插入,后者非常麻烦.所以每次利用kepeler.next.val和head.val比较大小,而不是kepeler.val和head.val比较大小,因为如果用后者,要把head指向的节点插入到kepeler指向的节点的前面,如果kepeler指向的节点是头结点,就更麻烦了. 代码如下: 1 /** 2 * Defi

leetcode 刷题之路 93 Merge k Sorted Lists

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 将k个有序链表合并成一个有序链表. 思路,之前做过两个有序链表的合并操作,对于k个链表,我们最先想到的就是能不能转化为我们熟悉的两个链表的合并,可以我们先将k个链表分为两部分,先对这两部分完成链表的有序合并操作,再对合并得到的两个链表进行合并,这是一个递归性质的描述,采用递归很容易实现这个程序,和数组

【leetcode刷题笔记】Sort List

Sort a linked list in O(n log n) time using constant space complexity. 题解:实现一个链表的归并排序即可.主要分为三部分: 1.找到中点并返回的函数findMiddle; 2.归并函数merge; 3.排序函数sortList. 数组的findMiddle函数非常容易实现,链表就有一点tricky了.首先设置两个指针,一个slow初始化为head,一个fast初始化为head.next,然后slow一次走一步,fast一次走两

【leetcode刷题笔记】Add Two Numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3) + (5 -> 6 ->

LeetCode做题笔记之四

这次一口气放9道题~ LeetCode 23题,Hard! 归并K个有序链表.使用堆来做,一开始把K个链表的第一个元素放进数组,然后建堆.之后取出第一个元素(如果这个元素是nil元素,直接退出)放进归并后的链表,再从这个元素所在的链表取第一个元素放到原来元素的位子上,然后重新维护堆性质.如果那个链表已经没有元素,那就插入一个nil元素. 趁机用了用泛型方法,真好使!哨兵nil也不错,感谢算法导论! public class WrappedListNode {     public int val

leetcode 刷题之路 76 Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return 1->2->3. 删除排序链表中重复的节点,删除操作完成后,原链表中的重复节点只保留一个. 思路,遍历链表,如果当前节点和下一个节点重复