1. 程式人生 > >程式設計師程式碼面試指南 —— 連結串列問題(二)

程式設計師程式碼面試指南 —— 連結串列問題(二)

題目:給定一個連結串列的頭節點head,請你判斷是否為迴文結構
例如:1 —> 2 —> 1 ture
1 —> 2 —> 2 —> 1 true
1 —> 2 —> 3 flase
思路:可以使用棧這種資料結構,可以將整個單向連結串列分為前半區和後半區,然後將前半區的資料入棧,遍歷後半區的資料,將後半區的資料和棧進行比較,當棧空或者連結串列空,則說明是迴文
需要確定的問題:如何進行分割槽,矛盾所在是奇數連結串列和偶數連結串列的問題,
兩種策咯:(1)奇偶分情況討論,(2)遮蔽奇偶差異
這裡程式碼採用第二種:

public class ReverChain {
  public static void main(String[] args) {
    Node head = new Node(1);
    Node node1 = new Node(2);
    Node node2 = new Node(1);
    head.next = node1;
    node1.next = node2;
    System.out.println(isRever(head));
  }
 
  private static boolean isRever(Node head) {
    int time = 0;
    Node h = head;
    while (h != null) {
      h = h.next;
      time++;
    }
 
    // 遮蔽奇偶差異
    double point = (double) time / 2;
    int end = (int) Math.floor(point);
    int begin = (int) Math.ceil(point) + 1;
 
    int i = 0;
    Stack<Node> stack = new Stack<>();
    while (i < end) {
      stack.push(head);
      head = head.next;
      i++;
    }
 
    // 遮蔽奇偶差異
    if (begin != end + 1) {
      head = head.next;
    }
 
    i = begin;
    while (i <= time) {
      if (stack.peek().value == head.value) {
        stack.pop();
        head = head.next;
      } else {
        break;
      }
      i++;
    }
    if (stack.isEmpty()) {
      return true;
    }
    return false;
  }
}

題目二:將單鏈表按某值劃分成左邊小,中間相等,右邊大的形式
描述: 給定一個單項鍊表頭節點head,節點的值型別是整形,再給定一個整數pivot,實現一個調整連結串列的函式,將連結串列調整成左邊部分的值都小於pivot的節點,中間部分的值都等於pivot的節點,右邊部分都是值大於pivot的節點。
程式碼:

public static void main(String[] args) {
  Node head = new Node(1);
  Node node1 = new Node(4);
  Node node2 = new Node(2);
  Node node3 = new Node(3);
  Node node4 = new Node(5);
  Node node5 = new Node(7);
  head.next = node1;
  node1.next = node2;
  node2.next = node3;
  node3.next = node4;
  node4.next = node5;
  int pivot = 3;
  Node h = sortChain(head, pivot);
  while (h != null) {
    System.out.println(h.value + " ");
    h = h.next;
  }
}
 
private static Node sortChain(Node head, int pivot) {
  // 0 為邏輯值,拼接時刪除
  Node big = new Node(0);
  Node equals = new Node(0);
  Node small = new Node(0);
  // 記錄初始位置
  Node bigStart = big;
  Node equalsStart = equals;
  Node smallStart = small;
 
  // 分離
  while (head != null) {
    if (head.value == pivot) {
      equals.next = new Node(head.value);
      equals = equals.next;
    } else if (head.value > pivot) {
      big.next = new Node(head.value);
      big = big.next;
    } else {
      small.next = new Node(head.value);
      small = small.next;
    }
    head = head.next;
  }
 
  // 拼接
  Node res = new Node(0);
  Node resStart = res;
 
  if (smallStart.next != null) {
    res.next = smallStart.next;
    res = small;
  }
  if (equalsStart.next != null) {
    res.next = equalsStart.next;
    res = equals;
  }
  if (bigStart.next != null) {
    res.next = bigStart.next;
    res = big;
  }
  return resStart.next;
}