• leetcode — reorder-list


    /**
     * Source : https://oj.leetcode.com/problems/reorder-list/
     *
     * Given a singly linked list L: L0→L1→…→Ln-1→Ln,
     * reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
     *
     * You must do this in-place without altering the nodes' values.
     *
     * For example,
     * Given {1,2,3,4}, reorder it to {1,4,2,3}.
     */
    public class RecordList {
    
    
        /**
         * 将链表的后半部分翻转之后依次插入链表前半部分每个元素后面
         *
         * 设链表长度为n
         * 1. 找到链表后半部分起始位置: n/2+1,使用双指针法,slow每次移动一个,fast每次移动两个,fast移动到最后的时候,slow指向的正好是 n/2+1
         * 2. 反转后半部分连链表
         * 3. 将反转后的后半部分链表依次插入前半部分,left指向左边,right指向反转后的第一个node,依次插入left的后一个,直到right指向null,
         *      right每次移动一个node,left每次移动2个node(因为刚刚left后面插入一个节点)
         *
         * @param head
         * @return
         */
        public LinkedNode record (LinkedNode head) {
            if (head == null || head.next == null) {
                return head;
            }
            LinkedNode midNode = findMidNode(head);
            LinkedNode reversedList = reverse(midNode);
            LinkedNode left = head;
            LinkedNode right = reversedList;
    
            while (right != null && right.next != null) {
                // 记录将要被插入的元素
                LinkedNode target = right;
                // 下一个需要被插入的元素
                right = right.next;
                // 插入target到链表中
                target.next = left.next;
                left.next = target;
                left = left.next.next;
            }
    
            return head;
        }
    
    
        private LinkedNode findMidNode (LinkedNode head) {
            LinkedNode slow = head;
            LinkedNode fast = head;
            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            return slow;
        }
    
    
        private LinkedNode reverse (LinkedNode head) {
            LinkedNode p = head;
            LinkedNode pre = null;
            while (p != null) {
                LinkedNode next = p.next;
                p.next = pre;
                pre = p;
                p = next;
            }
            return pre;
        }
    
        private class LinkedNode {
            int value;
            LinkedNode next;
    
        }
    
        /**
         * 创建普通的链表
         * @param arr
         * @return
         */
        public LinkedNode createList (int[] arr) {
            if (arr.length == 0) {
                return null;
            }
            LinkedNode head = new LinkedNode();
            head.value = arr[0];
            LinkedNode pointer = head;
            for (int i = 1; i < arr.length; i++) {
                LinkedNode node = new LinkedNode();
                node.value = arr[i];
                pointer.next = node;
                pointer = pointer.next;
            }
            return head;
        }
    
        private static void print (LinkedNode head) {
            if (head == null) {
                System.out.println("[]");
            }
            StringBuffer stringBuffer = new StringBuffer("[");
            while (head != null) {
                stringBuffer.append(head.value);
                stringBuffer.append(",");
                head = head.next;
            }
            stringBuffer.deleteCharAt(stringBuffer.length()-1);
            stringBuffer.append("]");
            System.out.println(stringBuffer);
        }
    
    
        public static void main(String[] args) {
            RecordList recordList = new RecordList();
            int[] arr = new int[]{1,2,3,4,5,6};
            print(recordList.record(recordList.createList(arr)));
    
        }
    }
    
  • 相关阅读:
    LeetCode
    LeetCode
    LeetCode
    位运算实现加法运算
    反转字符串
    数组中的逆序对
    矩阵中的路径
    机器人的运动范围
    滑动窗口的最大值
    HTML5全屏浏览器兼容方案
  • 原文地址:https://www.cnblogs.com/sunshine-2015/p/7906585.html
Copyright © 2020-2023  润新知