前幾日,看到一道面試題,每k個結點反轉一次鏈表,要求輸出反轉后的鏈表。
題目意思如下:
原鏈表:1,2,3,4,5,6,7,8
k = 3
新鏈表:3,2,1,6,5,4,8,7
覺得還是有點意思,今天便做了,思路是把原鏈表先按k切割成多份,再把每一份都反轉並拼接起來。
把代碼貼出來供大家參考
public class Node { public int v; public Node next; public Node(int v, Node next) { this.v = v; this.next = next; } public Node(int v) { this.v = v; } public Node() { } public static Node getNode(int ... arr) { Node head = new Node(); Node root = head; for (int i : arr) { head.next = new Node(i); head = head.next; } return root.next; } /** * 反轉鏈表 */ public static Node reverse(Node head) { if (head == null) { return null; } Node pre = null; Node cur = head; Node aft = head.next; while (aft != null) { cur.next = pre; pre = cur; cur = aft; aft = aft.next; } cur.next = pre; return cur; } /** * 每k位反轉 */ public static Node reverseK(Node head, int k) { List<CutRes> cutResList = new ArrayList<>(); while (head != null) { CutRes cutRes = cut(head, k); cutResList.add(cutRes); head = cutRes.newHead; } Node cur = new Node(); Node pre = cur; for (CutRes cutRes : cutResList) { cur.next = Node.reverse(cutRes.head); cur = cutRes.head; } return pre.next; } /** * 從頭部切割鏈表 * @param head 原頭部 * @param k 切割長度 */ public static CutRes cut(Node head, int k) { if (k <= 0) { return new CutRes(null, head); } Node cur = head; int i = 0; while (cur.next != null && ++i < k) { cur = cur.next; } Node tail = cur; Node newHead = cur.next; tail.next = null; return new CutRes(head, newHead); } static class CutRes { Node head; //切割得到的頭部 Node newHead; //切割后剩余的頭部 public CutRes(Node head, Node newHead) { this.head = head; this.newHead = newHead; } @Override public String toString() { return head.toString(); } } @Override public String toString() { StringBuilder sb = new StringBuilder("["); Node cur = next; sb.append(v); while (cur != null) { sb.append(", "); sb.append(cur.v); cur = cur.next; } sb.append(']'); return sb.toString(); } }