首页 > 试题广场 >

翻转链表

[编程题]翻转链表
  • 热度指数:5702 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

对于一个链表 L: L0→L1→…→Ln-1→Ln,
将其翻转成 L0→Ln→L1→Ln-1→L2→Ln-2→…

输入是一串数字,请将其转换成单链表格式之后,再进行操作


输入描述:
一串数字,用逗号分隔


输出描述:
一串数字,用逗号分隔
示例1

输入

1,2,3,4,5

输出

1,5,2,4,3

备注:
数组长度不超过100000
694ms 35300KB Java

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    class ListNode {
        int value;
        ListNode next;

        ListNode(int i) {
            this.value = i;
        }
    }

    /**
     * 1. 根据输入生成链表
     * 2. 反转生成一个新链表
     * 3. 交叉取原链表和新链表的节点,取前n个
     */
    public static void main(String[] args) {
        new Main().print();
    }

    private void print() {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        String[] chars = s.split(",");
        int[] arr = new int[chars.length];
        // 根据输入生成数组
        for (int i = 0; i < chars.length; i++) {
            arr[i] = Integer.parseInt(chars[i]);
        }

        int num = arr.length;
        if (num == 0) {
            return;
        }
        // 根据数组生成链表
        ListNode head = listfy(arr, num);
        ListNode result = revertn(head, num);
        for (int i = 0; i < num; i++) {
            if (i == num - 1) {
                System.out.print(result.value);
            } else {
                System.out.print(result.value + ",");
            }
            result = result.next;
        }
    }

    private ListNode listfy(int[] arr, int num) {
        ListNode virtualHead = new ListNode(0);
        ListNode temp = new ListNode(arr[0]);
        virtualHead.next = temp;
        for (int i = 1; i < num; i++) {
            temp.next = new ListNode(arr[i]);
            temp = temp.next;
        }
        return virtualHead.next;
    }

    private ListNode revertn(ListNode head, int num) {
        // 新生成一个反转链表(注意需要新生成链表而不是修改原来的链表)
        ListNode revertHead = revert(head);
        return merge(head, revertHead, num);
    }

    private ListNode revert(ListNode head) {
        ListNode temp = head;
        ListNode revertHead = new ListNode(0);
        ListNode newNode = null;
        while (temp != null) {
            newNode = new ListNode(temp.value);
            newNode.next = revertHead.next;
            revertHead.next = newNode;
            temp = temp.next;
        }
        return revertHead.next;
    }

    private ListNode merge(ListNode head, ListNode revertHead, int num) {
        if (num == 0) {
            return null;
        }
        ListNode temp = head.next;
        head.next = merge(revertHead, temp, --num);
        return head;
    }
}


发表于 2023-02-12 13:41:14 回复(0)

练习链表输入输出

import java.util.*;
import java.io.*;
public class Main{

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

    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        String[] s = str.split(",");
        ListNode head = new ListNode(0);
        ListNode tail = head;
        for(String _s : s){
            ListNode newNode = new ListNode(Integer.parseInt(_s));
            tail.next = newNode;
            tail = newNode;
        }
        reorderList(head.next);
        head = head.next;

        while(head != null){
            if(head.next == null) System.out.print(head.val);
            else System.out.print(head.val + ",");
            head = head.next;
        }

    }
    //找到链表中点,反转链表,合并两个链表
    public static void reorderList(ListNode head){
        if(head == null || head.next == null) return;
        ListNode mid = getMid(head);
        ListNode l2 = mid.next;
        l2 = reverseList(l2);
        mid.next = null;
        merge(head, l2);
    }

    //找到链表中点
    public static ListNode getMid(ListNode node){
        ListNode s = node, f = node;
        while(f != null && f.next != null){
            s = s.next;
            f = f.next.next;
        }
        return s;
    }

    //反转链表
    public static ListNode reverseList(ListNode node){
        ListNode pre = null;
        ListNode cur = node;
        while(cur != null){
            ListNode ne = cur.next;
            cur.next = pre;
            pre = cur;
            cur = ne;
        }
        return pre;
    }

    //合并连个链表
    public static void merge(ListNode l1, ListNode l2){
        ListNode p1 = l1, p2 = l2;
        while(l1 != null && l2 != null){
            p1 = l1.next; p2 = l2.next;
            l1.next = l2; l1 = p1;
            l2.next = l1; l2 = p2;
        }
    }
}
发表于 2022-02-26 16:59:56 回复(0)
import java.util.Scanner;

/*
题目描述:对于一个链表 L: L0→L1→…→Ln-1→Ln,将其翻转成 L0→Ln→L1→Ln-1→L2→Ln-2→…
输入1,2,3,4,5     输出1,5,2,4,3
备注:数组长度不超过100000
 */
public class Main {
    //定义Node节点
    static class ListNode {
        int val;
        ListNode next = null;

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

    public static void main(String[] args) {
        //1.获取控制台输入的信息
        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        String[] strings = string.split(",");
        //2.将输入的字符串构成带头节点的2个链表
        ListNode head = creatList(strings);
        reorderList(head.next);
        head = head.next;
        //3.输出
        while(head!=null){
            if(head.next==null){
                System.out.print(head.val);
            }else{
                 System.out.print(head.val+",");
            }
            head=head.next;
        }

    }



    /*
     * 将str创建带头结点的单链表
     */
    public static ListNode creatList(String[] strings) {
        ListNode head = new ListNode(0);
        ListNode tail = head;
        for (String str : strings) {
            ListNode newNode = new ListNode(Integer.valueOf(str));
            tail.next = newNode;
            tail = newNode;
        }
        return head;
    }


    /*
     * 思路:链表平均拆分,后半部分链表反转,在将两个链表合并
     */
    public static void reorderList(ListNode head) {
        if (head == null || head.next == null) return;

        ListNode p1 = head;
        ListNode p2 = head;

        // 找到链表的一半
        while (p2.next != null && p2.next.next != null) {
            p1 = p1.next;
            p2 = p2.next.next;
        }

        // 将链表分为两段
        p2 = p1.next;
        p1.next = null;
        p1 = head;

        // 将后半段进行链表的翻转
        ListNode head2 = p2;
        ListNode next2;
        while (p2.next != null) {
            next2 = p2.next;
            p2.next = next2.next;
            next2.next = head2;
            head2 = next2;
        }
        p2 = head2;

        // 两条链表进行合并
        ListNode next1;
        while (p2 != null) {
            next1 = p1.next;
            next2 = p2.next;

            p1.next = p2;
            p2.next = next1;

            p1 = next1;
            p2 = next2;
        }

    }

}



编辑于 2019-09-11 13:09:14 回复(0)

热门推荐

通过挑战的用户

查看代码