zoukankan      html  css  js  c++  java
  • [算法]头条面试—奇数位升序偶数位降序链表排序

    题目描述:一个链表,奇数位升序偶数位降序,让链表变成升序的。

    比如:1 8 3 6 5 4 7 2 9,最后输出1 2 3 4 5 6 7 8 9。

    分析:

    这道题可以分成三步:

    首先根据奇数位和偶数位拆分成两个链表。

    然后对偶数链表进行反转。

    最后将两个有序链表进行合并。

    package com.darrenchan.list;
    
    public class OddIncreaseEvenDecrease {
        /**
         * 按照奇偶位拆分成两个链表
         * @param head
         * @return
         */
        public static Node[] getLists(Node head){
            Node head1 = null;
            Node head2 = null;
            
            Node cur1 = null;
            Node cur2 = null;
            int count = 1;//用来计数
            while(head != null){
                if(count % 2 == 1){
                    if(cur1 != null){
                        cur1.next = head;
                        cur1 = cur1.next;
                    }else{
                        cur1 = head;
                        head1 = cur1;
                    }
                }else{
                    if(cur2 != null){
                        cur2.next = head;
                        cur2 = cur2.next;
                    }else{
                        cur2 = head;
                        head2 = cur2;
                    }
                }
                head = head.next;
                count++;
            }
            //跳出循环,要让最后两个末尾元素的下一个都指向null
            cur1.next = null;
            cur2.next = null;
            
            Node[] nodes = new Node[]{head1, head2};
            return nodes;
        }
        
        /**
         * 反转链表
         * @param head
         * @return
         */
        public static Node reverseList(Node head){
            Node pre = null;
            Node next = null;
            while(head != null){
                next = head.next;
                head.next = pre;
                pre = head;
                head = next;
            }
            return pre;
        }
        
        /**
         * 合并两个有序链表
         * @param head1
         * @param head2
         * @return
         */
        public static Node CombineList(Node head1, Node head2){
            if(head1 == null || head2 == null){
                return head1 != null ? head1 : head2;
            }
            Node head = head1.value < head2.value ? head1 : head2;
            Node cur1 = head == head1 ? head1 : head2;
            Node cur2 = head == head1 ? head2 : head1;
            Node pre = null;
            Node next = null;
            while(cur1 != null && cur2 != null){
                if(cur1.value <= cur2.value){//这里一定要有=,否则一旦cur1的value和cur2的value相等的话,下面的pre.next会出现空指针异常
                    pre = cur1;
                    cur1 = cur1.next;
                }else{
                    next = cur2.next;
                    pre.next = cur2;
                    cur2.next = cur1;
                    pre = cur2;
                    cur2 = next;
                }
            }
            pre.next = cur1 == null ? cur2 : cur1;
            
            return head;
        }
        
        public static void main(String[] args) {
            Node head = init();
            Node[] lists = getLists(head);
            
            Node head1 = lists[0];
            Node head2 = lists[1];
            head2 = reverseList(head2);
            
            head = CombineList(head1, head2);
            while(head != null){
                System.out.println(head.value);
                head = head.next;
            }
        }
        
        public static Node init(){
            Node node1 = new Node(1);
            Node node2 = new Node(8);
            Node node3 = new Node(3);
            Node node4 = new Node(6);
            Node node5 = new Node(5);
            Node node6 = new Node(4);
            Node node7 = new Node(7);
            Node node8 = new Node(2);
            Node node9 = new Node(9);
            
            node1.next = node2;
            node2.next = node3;
            node3.next = node4;
            node4.next = node5;
            node5.next = node6;
            node6.next = node7;
            node7.next = node8;
            node8.next = node9;
            return node1;
        }
    }

    合并两个单链表,还可以采用递归的方式:

    public class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            if(l1 == null && l2 == null)
                return null;
            if(l1 == null)
                return l2;
            if(l2 == null)
                return l1;
            ListNode head = null;
            if(l1.val > l2.val)
            {
                 head = l2;
                 head.next = mergeTwoLists(l1, l2.next);
            }
            else
            {
                 head = l1;
                 head.next = mergeTwoLists(l1.next, l2);
            }
            return head;
        }
    }
  • 相关阅读:
    ACM进阶计划
    《算法竞赛入门经典》习题——Chapter 3
    js运算符
    Javascript的数据类型简述
    JS事件处理和事件对象
    对一道代码的看法
    SOA不是Web Service
    梳理一下最近要重点好学的东西
    ReportViewer使用手册
    Lesson 9
  • 原文地址:https://www.cnblogs.com/DarrenChan/p/8764608.html
Copyright © 2011-2022 走看看