反轉單向和雙向連結串列 & 反轉部分單向連結串列
阿新 • • 發佈:2021-11-10
反轉單向和雙向連結串列
題目:反轉單向和雙向連結串列
《程式設計師程式碼面試指南》第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,自行改一下吧)