鏈表基礎訓練(一)
阿新 • • 發佈:2019-02-16
public args alt aps obj app 倒數 sof 不能
題目一:
刪除鏈表中的重復元素。
思路:一是利用哈希表(HashSet),哈希表特別適合於判斷集合中是否有重復的元素。二是直接使用遍歷鏈表,使用兩層for循環去遍歷再來找出重復的元素。下面給出第一種方法的代碼。
1 import java.util.HashSet; 2 3 public class 刪除重復結點 { 4 // 創建鏈表的節點 5 private static class ListNode { 6 ListNode next; 7 Object value; 8 9 publicView CodeListNode(Object value){ 10 super(); 11 this.value = value; 12 } 13 } 14 15 public static void main(String[] args){ 16 int data[] = {1, 6, 6, 7, 3, 3, 5, 3, 8, 9, 10, 10}; // 輸出 1 6 7 3 5 8 9 10 17 //啞元 空節點 18 ListNode head = new ListNode(null); 19 ListNode p = head; 20 for(int i = 0; i < data.length; i++){ 21 p.next = new ListNode(data[i]); 22 //指針往下進行移動 23 p = p.next; 24 } 25 removeReptition(head); 26 ListNode p1 = head.next; 27 while(p1 != null){ 28 System.out.print(p1.value + " "); 29 p1 = p1.next; 30 } 31 } 32 33 private static void removeReptition(ListNode head){ 34 ListNode p = head.next; 35 ListNode pre = head; 36 HashSet set = new HashSet(); 37 //遍歷哈希表 38 while(p != null){ 39 if(set.contains(p.value)){ 40 pre.next = p.next; 41 }else{ 42 set.add(p.value); 43 pre = p; 44 } 45 p = p.next; 46 } 47 } 48 }
題目二:
實現一個算法,輸出單向鏈表中的第k個節點。
思路: 從題目可以看出,只是給出了鏈表的頭結點,所以我們是不知道鏈表中含有幾個元素,假如知道幾個元素的話那就很簡單了。由於我們這裏只知道頭節點,我們可以使用一種叫快行指針(雙行指針)的技巧來解決這道題目。
1 public class 倒數第k個節點 { 2 // 特別要註意邊界的問題 3 public static ListNode FindKthToTail(ListNode head, int k) { 4 if (head == null || k <= 0) 5 return null; 6 ListNode p1 = head; 7 ListNode p2 = head; 8 int count = 0; 9 while (p2 != null && count < k) { 10 p2 = p2.next; 11 count++; 12 } // p2 與 p1 相差 k 距離 13 if (count < k) { 14 return null; 15 } 16 while (p2 != null) { // 當p2為null時,p1就指向了要刪除的那個節點。 17 p1 = p1.next; 18 p2 = p2.next; 19 } 20 // System.out.println(p1.data); 21 return p1; 22 } 23 24 public static void main(String[] args) { 25 int[] arr = { 1, 2, 3, 4, 5 }; 26 ListNode head = new ListNode(arr[0]);// 啞元 27 ListNode p = head; 28 for (int i = 1; i < arr.length; i++) { 29 p.next = new ListNode(arr[i]); 30 p = p.next; 31 } 32 // System.out.println(head); 33 ListNode l1 = FindKthToTail(head, 3); 34 System.out.println("倒數第三個節點:" + l1.val); 35 36 } 37 // 5,{1,2,3,4,5} 38 } 39 class ListNode { 40 int val; 41 ListNode next = null; 42 43 ListNode(int val) { 44 this.val = val; 45 } 46 47 @Override 48 public String toString() { 49 StringBuilder sb = new StringBuilder(val + ""); 50 ListNode nnext = next; 51 while (nnext != null) { 52 sb.append(nnext.val); 53 nnext = nnext.next; 54 } 55 return sb.toString(); 56 } 57 }View Code
結果:
題目三:
實現一個算法,刪除單向鏈表中的某個節點,假定你只能訪問該節點。輸入單向鏈表a->b->c->d->e中的c,結果不返回任何數據,單鏈表變為a->b->d->e。給定待刪除的節點,請執行刪除操作,若該節點為尾節點,返回false,否則返回true。
思路:題目中限定了只能訪問該節點,那麽之前的節點我們是不能夠訪問到的,所以只能訪問到節點以及通過next來訪問下面的節點。我們可以使用到一種特別的技巧就是復制當前節點的後繼節點的內容給當前節點,然後改變當前節點的指向跳過後繼直接指向後繼的下一個元素。當傳入的節點是最後一個節點的時候我們是不能夠進行刪除的,因為最後一個節點的next為空我們不能夠復制內容來進行刪除的,所以直接返回false。
1 public class 刪除某節點 { 2 public static boolean removeNode(ListNode pNode) { 3 if (pNode.next == null) 4 return false; 5 pNode.val = pNode.next.val;// 復制後繼的內容 6 pNode.next = pNode.next.next;// 跨越後繼 7 return true; 8 } 9 public static void main(String[] args) { 10 int[] arr = { 1, 2, 3, 4, 5 }; 11 ListNode head = new ListNode(arr[0]);// 啞元 12 ListNode p = head; 13 for (int i = 1; i < arr.length; i++) { 14 p.next = new ListNode(arr[i]); 15 p = p.next; 16 } 17 ListNode p1 = head.next; 18 removeNode(p1); 19 while(head!=null){ 20 System.out.println(head.val); 21 head = head.next; 22 } 23 } 24 } 25 class ListNode { 26 int val; 27 ListNode next = null; 28 29 ListNode(int val) { 30 this.val = val; 31 } 32 33 @Override 34 public String toString() { 35 StringBuilder sb = new StringBuilder(val + ""); 36 ListNode nnext = next; 37 while (nnext != null) { 38 sb.append(nnext.val); 39 nnext = nnext.next; 40 } 41 return sb.toString(); 42 } 43 }View Code
結果:
鏈表基礎訓練(一)