链表相关面试题
public class Code01_LinkedListMid {public static void main(String[] args) {}public static class Node{public int value;public Node next;public Node(int v){this.value = v;}}// 1 2 3 4 5 返回中點或上中點public static Node midOrUpMidNode(Node head){if(null == head || head.next == null || head.next.next==null){return head;}// 鏈表有3個點或以上Node slow = head.next;Node fast = head.next.next;while(null != fast.next && null != fast.next.next){slow = slow.next;fast = fast.next.next;}return slow;}// 1 2 3 4 5 返回中點或下中點public static Node midOrDownMidNode(Node head){if(null == head || head.next == null){return head;}Node slow = head.next;Node fast = head.next;while(null != fast.next && null != fast.next.next){slow = slow.next;fast = fast.next.next;}return slow;}// (中點或上中點)的前一個 1 2 3 4 5public static Node midOrUpMidPreNode(Node head){if(null == head || head.next == null || head.next.next==null){return null;}Node slow = head;Node fast = head.next.next;while(null != fast.next && null != fast.next.next){slow = slow.next;fast = fast.next.next;}return slow;}// (中點或下中點)的前一個 1 2 3 4 5public static Node midOrDownMidPreNode(Node head){if(null == head || head.next == null){return null;}if(head.next.next == null){return head;}Node slow = head;Node fast = head.next;while(null != fast.next && null != fast.next.next){slow = slow.next;fast = fast.next.next;}return slow;}
}
?
判斷一個鏈表是否是回文結構
public class IsPalindromeTest {public static void main(String[] args) {Node n1 = new Node(1);Node n2 = new Node(2);Node n3 = new Node(3);Node n4 = new Node(2);Node n5 = new Node(1);n1.next = n2;n2.next = n3;n3.next = n4;n4.next = n5;System.out.println(isPalindrome(n1));}public static class Node{private int value;private Node next;public Node(int value){this.value = value;}}public static boolean isPalindrome(Node head){if(null == head || head.next == null){return true;}Node n1 = head;Node n2 = head;while(n2.next != null && n2.next.next != null){n1 = n1.next;n2 = n2.next.next;}n2 = n1.next;n1.next = null;Node n3 = null;// 逆序鏈表while(n2 != null){n3 = n2.next; // save next noden2.next = n1; // next of right node convertn1 = n2; // n1 moven2 = n3; // n2 move}n3 = n1; // save last node 最后一個節點n2 = head; // 左邊第一個節點boolean res = true;while(n2 != null && n1 != null){if(n2.value != n1.value){res = false;break;}n1 = n1.next;n2 = n2.next;}// 將逆序的鏈表再還原回來n1 = n3.next;n3.next = null;while(n1 != null){n2 = n1.next;n1.next = n3;n3 = n1;n1 = n2;}return res;} }?
給出一個鏈表,小于某個數的放在鏈表左邊,等于某個數的放在鏈表中間,大于某個數的放在鏈表右邊
public class SmallEqualsBigger {public static void main(String[] args) {Node n1 = new Node(5);Node n2 = new Node(3);Node n3 = new Node(3);Node n4 = new Node(2);Node n5 = new Node(1);Node n6 = new Node(6);n1.next = n2;n2.next = n3;n3.next = n4;n4.next = n5;n5.next = n6;n1 = listPartition2(n1,3);while(n1 != null){System.out.print(n1.value+ " ");n1 = n1.next;}}public static class Node{private int value;private Node next;public Node(int value){this.value = value;}}// 方法一public static Node listPartition1(Node head, int pivot){if(head == null){return head;}Node cur = head;int i = 0;while(cur != null){i++; // 計算出鏈表節點的總個數cur = cur.next;}Node[] nodeArr = new Node[i];i = 0;cur = head;// 把鏈表放到數組中for (i = 0; i < nodeArr.length; i++) {nodeArr[i] = cur;cur = cur.next;}arrPartition(nodeArr, pivot);for (i = 1; i != nodeArr.length; i++) {nodeArr[i-1].next = nodeArr[i];}nodeArr[i-1].next = null; // 最后一個節點return nodeArr[0];// 返回新的頭節點}public static void arrPartition(Node[] nodeArr, int pivot){int small = -1;int big = nodeArr.length;int index = 0;while(index<big){if(nodeArr[index].value < pivot){swap(nodeArr,index++,++small);}else if(nodeArr[index].value == pivot){index++;}else if(nodeArr[index].value > pivot){swap(nodeArr,index,--big);}}}public static void swap(Node[] nodeArr, int node1, int node2){Node temp = nodeArr[node1];nodeArr[node1] = nodeArr[node2];nodeArr[node2] = temp;}// 方法二public static Node listPartition2(Node head, int pivot){// 使用6個變量Node sH = null; // small headNode sT = null; // small tailNode eH = null; // equal headNode eT = null; // equal tailNode bH = null; // big headNode bT = null; // big tailNode next = null; // save next nodewhile(head != null){next = head.next;head.next = null;if(head.value < pivot){if(sH == null){sH = head;sT = head;}else{sT.next = head;sT = head;}}else if(head.value == pivot){if(eH == null){eH = head;eT = head;}else{eT.next = head;eT = head;}}else {if(bH == null){bH = head;bT = head;}else{bT.next = head;bT = head;}}head = next;}if(sT != null){sT.next = eH;eT = eT == null ? sT : eT; // 下一步,誰去連大于區域的頭,誰就變成eT}if(eT != null){eT.next = bH;}sH = sH == null ? (eH == null ? bH: eH): sH;return sH;} }?
public class Code02_CopyListWithRand {public static void main(String[] args) {Node n1 = new Node(5);Node n2 = new Node(4);Node n3 = new Node(3);Node n4 = new Node(2);Node n5 = new Node(1);n1.next = n2;n2.next = n3;n3.next = n4;n4.next = n5;Node newN1 = copyListWithRand2(n1);while(null != newN1){System.out.print(newN1.value+" ");newN1 = newN1.next;}}public static class Node{public int value;public Node next;public Node random;public Node(int value){this.value = value;}}public static Node copyListWithRand2(Node head){if(null == head){return null;}Node cur = head;Node next = null;// 1 -> 2// 1 -> 1' -> 2while(null != cur){next = cur.next;// 新生成的節點,插入到原來節點后面cur.next = new Node(cur.value);cur.next.next = next;cur = next;}cur = head;Node curCopy = null;// 1 -> 1' -> 2 -> 2'while(null != cur){next = cur.next.next;curCopy = cur.next;curCopy.random = (cur.random == null ? null : cur.random.next);cur = next;}Node res = head.next;cur = head;while(cur != null){next = cur.next.next;curCopy = cur.next;cur.next = next;curCopy.next = (null != next ? next.next : null);cur = next; // cur.next = cur.next.next; // cur = cur.next;}return res;} }?
總結
- 上一篇: 数据结构-荷兰国旗问题
- 下一篇: <LINUX内核完全剖析:基于0.12内