1. 程式人生 > 其它 >反轉單向和雙向連結串列 & 反轉部分單向連結串列

反轉單向和雙向連結串列 & 反轉部分單向連結串列

反轉單向和雙向連結串列

題目:反轉單向和雙向連結串列

《程式設計師程式碼面試指南》第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,自行改一下吧)