Loading

反转单向和双向链表 & 反转部分单向链表

反转单向和双向链表

题目:反转单向和双向链表

《程序员代码面试指南》第15题 P47 难度:士★☆☆☆

本题很简单,但是我反转单向链表最开始居然没想到怎么做,还想着用递归,结果测试案例报了栈溢出的错误。。

反转单向链表断断续续想了1天多,终于开窍了。其实和双向链表一样

反转单双向链表都是从头结点开始修改next以及双向链表的last从头到尾遍历一遍,反转也就完成了。

牛客题解代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static class Node {
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }
    
    public static class DoubleNode {
        public int value;
        public DoubleNode last;
        public DoubleNode next;

        public DoubleNode(int value) {
            this.value = value;
        }
    }
    
    public static Node reverse(Node head) {
        Node pre = null;
        Node next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

    public static DoubleNode reverse(DoubleNode head) {
        DoubleNode pre = null;
        DoubleNode next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            head.last = next;
            pre = head;
            head = next;
        }
        return pre;
    }
    
    public static Node listGenerator(int length, String[] numbers) {
        Node head = new Node(Integer.parseInt(numbers[0]));
        Node cur = head;
        for (int i = 1; i < length; i++) {
            cur.next = new Node(Integer.parseInt(numbers[i]));
            cur = cur.next;
        }
        cur.next = null;
        return head;
    }

    public static DoubleNode doubleListGenerator(int length, String[] numbers) {
        DoubleNode head = new DoubleNode(Integer.parseInt(numbers[0]));
        head.last = null;
        DoubleNode cur = head;
        DoubleNode curNext;
        for (int i = 1; i < length; i++) {
            curNext = new DoubleNode(Integer.parseInt(numbers[i]));
            cur.next = curNext;
            curNext.last = cur;
            cur = cur.next;
        }
        cur.next = null;
        return head;
    }

    public static void printList(Node head) {
        while (head != null) {
            System.out.print(head.value +" ");
            head = head.next;
        }
        System.out.println();
    }

    public static void printList(DoubleNode head) {
        while (head != null) {
            System.out.print(head.value +" ");
            head = head.next;
        }
        System.out.println();
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(bufferedReader.readLine());
        String[] numbers1 = bufferedReader.readLine().split(" ");
        int m = Integer.parseInt(bufferedReader.readLine());
        String[] numbers2 = bufferedReader.readLine().split(" ");
        Node head1 = listGenerator(n, numbers1);
        DoubleNode head2 = doubleListGenerator(m, numbers2);
        head1 = reverse(head1);
        printList(head1);
        head2 = reverse(head2);
        printList(head2);
    }
}

(该代码中注意一下,输出改成用StringBuilder)

反转部分单向链表

题目:反转部分单向链表

《程序员代码面试指南》第16题 P48 难度:士★☆☆☆

本题也很简单,区别就在于要反转部分的链表。

首先要注意,1<=from<=to<=N不满足则不用调整,直接返回

然后,正常反转from到to之间的节点,然后注意from前一个节点和to后一个节点的连接问题即可;

不过还需要判断from是否为头结点返回新的头结点返回旧的头结点

牛客题解代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static class Node {

        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }
    
    public static Node reversePart(Node head, int from, int to) {
        Node node1 = head;
        Node begin = null;
        Node end = null;
        int len = 0;
        while (node1 != null) {
            len++;
            // 找到反转部分的前一个结点
            begin = len == from - 1 ? node1 : begin;
            // 找到反转部分的后一个结点
            end = len == to + 1 ? node1 : end;
            node1 = node1.next;
        }
        if (from > to || from < 1 || to > len) {
            return head;
        }
        node1 = begin == null ? head : begin.next;
        Node node2 = node1.next;
        node1.next = end;
        Node next = null;
        while (node2 != end) {
            next = node2.next;
            node2.next = node1;
            node1 = node2;
            node2 = next;
        }
        if (begin != null) {
            begin.next = node1;
            return head;
        } else {
            return node1;
        }
    }

    public static void printList(Node head) {
        while (head != null) {
            System.out.print(head.value +" ");
            head = head.next;
        }
        System.out.println();
    }
    
    public static Node listGenerator(int length, String[] numbers) {
        Node head = new Node(Integer.parseInt(numbers[0]));
        Node cur = head;
        for (int i = 1; i < length; i++) {
            cur.next = new Node(Integer.parseInt(numbers[i]));
            cur = cur.next;
        }
        cur.next = null;
        return head;
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(bufferedReader.readLine());
        String[] numbers = bufferedReader.readLine().split(" ");
        String[] parameters = bufferedReader.readLine().split(" ");
        int L = Integer.parseInt(parameters[0]);
        int R = Integer.parseInt(parameters[1]);
        Node head = listGenerator(n, numbers);
        head = reversePart(head, L, R);
        printList(head);
    }
}

(不知道为啥这2个代码输出都没有用StringBuilder,自行改一下吧)

posted @ 2021-11-10 15:04  幻梦翱翔  阅读(106)  评论(0)    收藏  举报