第11题 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}.

Solution1:用stack解题

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

        ListNode current = head;
        Stack<ListNode> tails = new Stack<ListNode>();
        int length =0;
        while(current!=null){
            tails.push(current);
            current=current.next;
            length++;
        }
        current = head;
        for(int position=0; position<length-2; position+=2){
            ListNode tail = tails.pop();
            tail.next = current.next;
            current.next = tail;
            current = current.next.next;
        }
        if(length%2!=0)   current.next=null;
        else current.next.next=null;

        return;
    }
}

Solution2:第一步,找到list的中点(用两个步长为1和2的指针实现);第二步,讲list后半部分翻转;第三步,讲list前后部分合并。这种方法不用记录长度为奇数或偶数。

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

        ListNode tail=head, mid=head;
        while(tail.next!=null && tail.next.next!=null){
            tail=tail.next.next;
            mid=mid.next;
        }
        //reverse the nodes after mid, produce 2 lists, first half list and second half list
        tail = mid.next;   //the tail of second half list is tail
        mid.next = null;    //first list from head to mid
        ListNode prev=null, next;
        while(tail!=null){//reverse list
                next = tail.next;
                tail.next = prev;
                prev = tail;
                if(next!=null)
                    tail=next;
                else
                    break;
        }
        //now tail is the head for the second half
        //merge two lists
        while(tail!=null){//use tail!=null because list started from tail is always shorter than list started from head
            next = tail.next;
            tail.next = head.next;
            head.next = tail;
            tail= next;
            head = head.next.next;

        }

        return;
    }
}

注意翻转list的操作里当next==null时表示遍历到原list尾,即翻转list的头部,则不执行tail=next操作,否则tail会指向null,丢失翻转list的头部。

两种方法执行前都要判断head或head.next或head.next.next是否为null,因为此方法要求list中至少有三个元素,否则可直接返回。

时间: 2024-11-06 18:37:29

第11题 Reorder List的相关文章

C#认证第一章1 题 11题

C#第一章第一题 C#认证第一章  11题

c#认证题第一单元 1题 11题.

第一题: 第11题:

第11题:求二叉树中节点的最大距离

欢迎转载,转载请务必注明出处:http://blog.csdn.net/alading2009/article/details/44984331 第11题:如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义"距离"为两点之间边的个数.写一个程序,求一棵二叉树中相距最远的两个节点之间的距离. 树的高度是一个重要信息,然后就可以祭出递归大法了. 代码 package test011; import test004.Node; /** * Created by cq o

OCP-1Z0-051-题目解析-第11题

11. View the Exhibit and examine the structure of the PRODUCTS table.All products have a list price. You issue the following command to display the total price of each product after a discount of 25% and a tax of 15% are  applied on it. Freight charg

第11题:移除数组中的重复元素

/* 前几天去爬泰山了,一直没更新,上山时还没什么感觉,下山后简直要崩溃啊,骨头都散了,继续更新...... */ 第11题:移除数组中的重复元素 给定一个升序排列的数组,去掉重复的数,并返回新的数组的长度. 例如: 数组A = {1, 1, 2},你的函数应该返回长度2,新数组为{1, 2} 要求: 不能新开数组分配额外的空间.即常数空间限制. 提示: 输入一个整数n,以及其对应的数组A[n],输出新数组长度 样例输入 5 0 0 1 1 2 样例输出 3 解析: #include <stdi

C++习题三10、11题

10.  某单位的职工工资包括基本工资Wage,岗位巾Subsidy,房租Rent,水费Waterfee,电费Elecfee,设计实现工资管理的类Salary,该类的形式如下: class salary{ private: double wage,subsidy,rent,waterfee,elecfee; public: salary(-----){初始化工资数据的各分项} salary(){初始化工资的各分项数据为0} void setXX (double f){xx=f;} double 

剑指Offer系列之题11~题15

目录 11.矩形覆盖 12.二进制中1的个数 13. 数值的整数次方 14.调整数组顺序使奇数位于偶数前面 15.链表中倒数第k个结点 11.矩形覆盖 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 比如n=3时,2*3的矩形块有3种覆盖方法: 斐波那契数列的应用 第一次竖着放一块类比为走一步,第一次横着放两块类比为走两步 代码与上面的斐波那契数列类题目类似,此处不再赘述:剑指Offer系列之题6~题10. 12.

leetcode第11题--Container With Most Water

Problem: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a

Two Points问题--之LeetCode 11题

---恢复内容开始--- Container with most  water--LeetCode11题 Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find t