leetCode-链表相关题目

133 阅读2分钟

LeetCode链表相关题目,后续继续补充

反转链表

  1. 题目
    leetcode.com/problems/re…
  2. 分析
    两种方法,递归和非递归写法。
  3. 代码
//非递归写法
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null) {
            return null;
        }
        //tmp 保留next.next值
        ListNode pre = head, next = head.next, tmp;
        pre.next = null;
        while (next != null) {
            tmp = next.next;
            next.next = pre;
            pre = next;
            next = tmp;
        }
        return pre;
    }
}

//递归写法
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) return head;
        ListNode result = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return result;
    }
    
}

交互相邻节点

1.题目
leetcode.com/problems/sw…

2.分析
使用递归

3.代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null) {
            return head;
        }
        ListNode next = head.next;
        if (next == null) {
            return head;
        }
        head.next = swapPairs(next.next);
        next.next = head;
        return next;
    }
}

判断链表是否有环

1.题目
leetcode.com/problems/li…

2.分析
方法1:使用HashSet保存每个节点,空间复杂度O(n),不推荐
方法2:使用快慢指针碰撞,空间复杂度O(1)

3.代码

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

查找链表

  1. 题目
    leetcode.com/problems/li…

  2. 分析
    上面一题的增强版,不仅需要判断链表是否有环,同时需要返回相交节点

  3. 代码

/**
 * 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) {
        //使用hashset记录节点
        Set<ListNode> nodes = new HashSet<>();
        ListNode p = head;
        while (p != null) {
            if (nodes.contains(p)) {
                return p;
            }
            nodes.add(p);
            p = p.next;
        }
        return null;
    }
}

方法2
/**
 * 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 slow = head, fast = head;
        int flag = 0;
        while (slow != fast || flag == 0) {
            flag = 1;
            if (fast == null || fast.next == null) {
                return null;
            }
            slow = slow.next;
            fast = fast.next.next;
        }
        //must have cycle
        slow = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}