[左神面试指南] 链表[下]篇

CDxxx 两个单链表相交的一系列问题⭐

  • 剑指offer 链表篇 JZ52 两个链表的第一个公共结点

  • 剑指offer 链表篇 JZ23 链表中环的入口结点

public Node getIntersectNode(Node head1, Node head2) {
    if (head1 == null || head2 == null) 
        return null;
    Node loop1 = getLoopNode(head1); // 判断是否有环
    Node loop2 = getLoopNode(head2); // 判断是否有环
    if (loop1 == null && loop2 == null) // 都没有环,判断是否相交
        return noLoop(head1, head2);
    if (loop1 != null && loop2 != null)  // 都有环,判断是否相交
        return bothLoop(head1, loop1, head2, loop2);
    return null;
}

CD119 将单链表的每 K 个节点之间逆序

/* 模拟 */
public class CD119_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head, int K)
    {
        ListNode fakeHead = new ListNode(-1), pre = fakeHead, tail = head, temp, front;
        int cnt = 1;
        fakeHead.next = head;
        while (tail != null)
        {
            if (cnt == K)
            {
                temp = tail.next;
                tail.next = null;
                front = pre.next;
                reverseList(pre.next);
                pre.next.next = temp;
                pre.next = tail;

                pre = front;
                tail = temp;
                cnt = 1;
            }
            cnt++;
            if (tail != null)
                tail = tail.next;
        }
        return fakeHead.next;
    }

    public static void reverseList(ListNode head)
    {
        ListNode tail = head.next, temp;
        head.next = null;
        while (tail != null)
        {
            temp = tail.next;
            tail.next = head;
            head = tail;
            tail = temp;
        }
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, K;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        K = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0], K);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

/* 栈 */
public class CD119_2
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head, int K)
    {
        ListNode fakeHead = new ListNode(-1), pre = fakeHead, tail = head, temp;
        fakeHead.next = head;
        int cnt = 1;
        while (tail != null)
        {
            if (cnt == K)
            {
                temp = tail.next;
                ListNode[] listNodes = reverseList(pre.next, tail);
                pre.next = listNodes[0];
                listNodes[1].next = temp;

                pre = listNodes[1];
                tail = temp;
                cnt = 1;
            }
            cnt++;
            if (tail != null)
                tail = tail.next;
        }
        return fakeHead.next;
    }

    public static ListNode[] reverseList(ListNode head, ListNode tail)
    {
        ListNode res = null, temp = null;
        Stack<ListNode> stack = new Stack<>();
        while (head != tail)
        {
            stack.add(head);
            head = head.next;
        }
        stack.add(tail);
        while (!stack.isEmpty())
        {
            ListNode popNode = stack.pop();
            if (res == null)
                res = temp = popNode;
            else
            {
                temp.next = popNode;
                temp = temp.next;
            }
        }
        return new ListNode[]{res, temp};
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, K;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        K = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0], K);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD137 删除无序单链表中值重复出现的节点

/* 模拟(超时,看思路即可) */
public class CD137_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head)
    {
        ListNode node = head, cur, pre;
        while (node != null)
        {
            pre = node;
            cur = node.next;
            while (cur != null)
            {
                if (cur.val == node.val)
                {
                    pre.next = cur.next;
                    cur.next = null;
                    cur = pre.next;
                    continue;
                }
                cur = cur.next;
                pre = pre.next;
            }
            node = node.next;
        }
        return head;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0]);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

/* 哈希 */
public class CD137_2
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head)
    {
        ListNode fakeHead = new ListNode(-1), tail = fakeHead;
        HashMap<Integer, ListNode> map = new HashMap<>();
        while (head != null)
        {
            if (!map.containsKey(head.val))
            {
                map.put(head.val, head);
                tail.next = head;
                tail = tail.next;
            }
            head = head.next;
        }
        tail.next = null;
        return fakeHead.next;
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0]);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD138 在单链表中删除指定值的节点

/* 模拟 */
public class CD138_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head, int NUM)
    {
        ListNode fakeHead = new ListNode(-1), cur = head, pre = fakeHead;
        fakeHead.next = head;
        while (cur != null)
        {
            if (cur.val == NUM)
            {
                pre.next = cur.next;
                cur.next = null;
                cur = pre.next;
                continue;
            }
            pre = pre.next;
            cur = cur.next;
        }
        return fakeHead.next;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, NUM;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        NUM = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0], NUM);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD156 将搜索二叉树转换成双向链表⭐

/* 队列 */
public class CD156_1
{
    public static class DoubleListNode
    {
        public int val;
        public DoubleListNode prev = null;
        public DoubleListNode next = null;

        public DoubleListNode(int val)
        {
            this.val = val;
        }
    }

    public static class TreeNode
    {
        public int val;
        public TreeNode left = null;
        public TreeNode right = null;

        public TreeNode(int val)
        {
            this.val = val;
        }

        public static TreeNode createTree(int[][] nums)
        {
            TreeNode[] tree = new TreeNode[nums.length + 1];
            Arrays.setAll(tree, TreeNode::new);
            for (int i = 0; i < nums.length; i++)
            {
                if (nums[i][1] != 0)
                    tree[nums[i][0]].left = tree[nums[i][1]];
                if (nums[i][2] != 0)
                    tree[nums[i][0]].right = tree[nums[i][2]];
            }
            return tree[nums[0][0]];
        }
    }

    public static DoubleListNode solution(TreeNode root)
    {
        Queue<TreeNode> que = new LinkedList<>();
        DoubleListNode fakeHead = new DoubleListNode(-1), tail = fakeHead;
        inOrder(root, que);
        while (!que.isEmpty())
        {
            TreeNode pollNode = que.poll();
            DoubleListNode temp = new DoubleListNode(pollNode.val);
            tail.next = temp;
            temp.prev = tail;
            tail = temp;
        }
        fakeHead.next.prev = null;
        return fakeHead.next;
    }

    public static void inOrder(TreeNode root, Queue<TreeNode> que)
    {
        if (root == null) return;
        inOrder(root.left, que);
        que.add(root);
        inOrder(root.right, que);
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[][] arr = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                arr[i][j] = in.nextInt();
        DoubleListNode res = solution(TreeNode.createTree(arr));
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

/* ⭐递归⭐ */
public class CD156_2
{
    public static class DoubleListNode
    {
        public int val;
        public DoubleListNode prev = null;
        public DoubleListNode next = null;

        public DoubleListNode(int val)
        {
            this.val = val;
        }
    }

    public static class TreeNode
    {
        public int val;
        public TreeNode left = null;
        public TreeNode right = null;

        public TreeNode(int val)
        {
            this.val = val;
        }

        public static TreeNode createTree(int[][] nums)
        {
            TreeNode[] tree = new TreeNode[nums.length + 1];
            Arrays.setAll(tree, TreeNode::new);
            for (int i = 0; i < nums.length; i++)
            {
                if (nums[i][1] != 0)
                    tree[nums[i][0]].left = tree[nums[i][1]];
                if (nums[i][2] != 0)
                    tree[nums[i][0]].right = tree[nums[i][2]];
            }
            return tree[nums[0][0]];
        }
    }

    public static DoubleListNode solution(TreeNode root)
    {
        return inOrder(root)[0];
    }

    public static DoubleListNode[] inOrder(TreeNode root)
    {
        if (root == null) return new DoubleListNode[]{null, null};
        DoubleListNode temp = new DoubleListNode(root.val);
        DoubleListNode left[] = inOrder(root.left);
        DoubleListNode right[] = inOrder(root.right);
        if (left[1] != null)
            left[1].next = temp;
        temp.prev = left[1];
        if (right[0] != null)
            right[0].prev = temp;
        temp.next = right[0];
        return new DoubleListNode[]{left[0] == null ? temp : left[0], right[1] == null ? temp : right[1]};
    }

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[][] arr = new int[N][3];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < 3; j++)
                arr[i][j] = in.nextInt();
        DoubleListNode res = solution(TreeNode.createTree(arr));
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD139 单链表的选择排序

/* 模拟 */
public class CD139_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head)
    {
        ListNode fakeHead = new ListNode(-1), pre, cur, temp, tempPre;
        fakeHead.next = head;
        head = fakeHead;
        int mmin;
        while (head != null)
        {
            tempPre = pre = head;
            temp = cur = head.next;
            mmin = Integer.MAX_VALUE;
            while (cur != null)
            {
                if (cur.val < mmin)
                {
                    mmin = cur.val;
                    temp = cur;
                    tempPre = pre;
                }
                cur = cur.next;
                pre = pre.next;
            }
            if (temp != null)
            {
                tempPre.next = temp.next;
                temp.next = head.next;
                head.next = temp;
            }
            head = head.next;
        }
        return fakeHead.next;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0]);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD157 一种怪异的节点删除方式

/* 模拟 */
public class CD157_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static void solution(ListNode head)
    {
        while (head != null && head.next != null)
        {
            head.val = head.next.val;
            if (head.next.next == null)
                head.next = null;
            head = head.next;
        }
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, M;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        M = in.nextInt();
        ListNode res = ListNode.createSingleList(l)[0], temp = res;
        while (--M > 0)
            temp = temp.next;
        solution(temp);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD158 向有序的环形单链表中插入新节点

/* 模拟 */
public class CD158_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            tail.next = head.next;
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head, int NUM)
    {
        ListNode cur = head.next, pre = head, tail = head;
        while (tail.next != head)
            tail = tail.next;
        if (NUM <= head.val)
        {
            ListNode newNode = new ListNode(NUM);
            newNode.next = head;
            tail.next = newNode;
            head = newNode;
        }
        else if (NUM >= tail.val)
        {
            ListNode newNode = new ListNode(NUM);
            tail.next = newNode;
            newNode.next = head;
        }
        else
        {
            while (cur != null)
            {
                if (pre.val <= NUM && NUM <= cur.val)
                {
                    ListNode newNode = new ListNode(NUM);
                    pre.next = newNode;
                    newNode.next = cur;
                    break;
                }
                pre = pre.next;
                cur = cur.next;
            }

        }
        return head;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, NUM;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        NUM = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0], NUM), head = res;
        while (res.next != head)
        {
            out.print(res.val + " ");
            res = res.next;
        }
        out.println(res.val);
        out.flush();
    }
}

CD159 合并两个有序的单链表

/* 归并 */
public class CD159_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head1, ListNode head2)
    {
        ListNode fakeHead = new ListNode(-1), cur = fakeHead;
        while (head1 != null && head2 != null)
        {
            if (head1.val <= head2.val)
            {
                cur.next = head1;
                cur = cur.next;
                head1 = head1.next;
            }
            else
            {
                cur.next = head2;
                cur = cur.next;
                head2 = head2.next;
            }
        }
        cur.next = (head1 == null ? head2 : head1);
        return fakeHead.next;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N, M;
        N = in.nextInt();
        int[] l1 = new int[N];
        for (int i = 0; i < N; i++)
            l1[i] = in.nextInt();
        M = in.nextInt();
        int[] l2 = new int[M];
        for (int i = 0; i < M; i++)
            l2[i] = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l1)[0], ListNode.createSingleList(l2)[0]);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}

CD160 按照左右半区的方式重新组合单链表

/* 模拟 */
public class CD160_1
{
    public static class ListNode
    {
        public int val;
        public ListNode next = null;

        public ListNode(int val)
        {
            this.val = val;
        }

        public static ListNode[] createSingleList(int[] nums)
        {
            ListNode head = new ListNode(-1), tail = head;
            for (int num : nums)
            {
                tail.next = new ListNode(num);
                tail = tail.next;
            }
            return new ListNode[]{head.next, tail};
        }
    }

    public static ListNode solution(ListNode head)
    {
        ListNode fakeHead = new ListNode(-1), pre = fakeHead, fast = head, slow = head, tail = fakeHead;
        fakeHead.next = head;
        boolean flag = true;
        while (fast != null && fast.next != null)
        {
            pre = pre.next;
            slow = slow.next;
            fast = fast.next.next;
        }
        pre.next = null;
        while (head != null && slow != null)
        {
            if (flag)
            {
                tail.next = head;
                tail = tail.next;
                head = head.next;
            }
            else
            {
                tail.next = slow;
                tail = tail.next;
                slow = slow.next;
            }
            flag = !flag;
        }
        tail.next = (head == null) ? slow : head;
        return fakeHead.next;
    }


    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int N;
        N = in.nextInt();
        int[] l = new int[N];
        for (int i = 0; i < N; i++)
            l[i] = in.nextInt();
        ListNode res = solution(ListNode.createSingleList(l)[0]);
        while (res != null)
        {
            out.print(res.val + (res.next == null ? "" : " "));
            res = res.next;
        }
        out.flush();
    }
}
posted @ 2023-11-09 13:50  Vivid-BinGo  阅读(3)  评论(0编辑  收藏  举报