聽說鏈表是面試是比較容易出現的數據結構。把leetcode上關於鏈表的題以前差很少刷完了。java
AC不過的最主要緣由就是考慮的狀況不徹底,尤爲是頭指針,以及最後一個元素,空指針等。面試
面試題第五題:從尾到頭打印鏈表編程
第一想法是用棧。數據結構
考慮到java中棧的定義爲:函數
Stack<ListNode> sk = new Stack<ListNode>();spa
判斷棧空的條件是sk.isEmpty()操作系統
第二個是用遞歸指針
每一次調用自身傳進去的參數是當前值的nextcode
public static void reverseList(ListNode head) { if (head == null && head.next == null) { System.out.println(head.val); } else { if (head.next != null) { reverseList(head.next); } } System.out.println(head.val); }
面試題13,:在O(1)的時間刪除鏈表結點blog
核心想法是爲了便於不記錄要刪除結點的上一個結點,把下一個節點的內容複製到須要刪除的節點上覆蓋原有的內容,至關於刪除了指定結點。可是必定要注意若是頭結點爲指定結點,指定結點爲最後一個節點的狀況。
所以,當刪除一個節點時,並不必定要刪除這個結點自己,能夠把下一個節點的內容複製出來覆蓋被刪除結點的內容,而後再把下一個節點刪除!
下面代碼只是將最核心的展現,並無考慮頭結點以及尾結點
public static ListNode deleteNode(ListNode head, ListNode de){ ListNode newHead = head; while(head.val!=de.val&&head.next!=null){ head = head.next; } head.val = head.next.val; head = head.next; return newHead; }
一樣,編程之美3.4節中無頭鏈表中刪除指定結點
函數的參數只是指明瞭要刪除的結點current
所以咱們先要找到Current 的下一個節點,而後用current.next.val去覆蓋當前的Current.val
而後current = current.next.next
不是很明白有頭鏈表和無頭鏈表的區別?
另外在編程之美上還有一道題比較有意思就是判斷兩個鏈表是否相交
比較好的方法有兩個:
1、將其中一個鏈表首尾相連,檢測另一個鏈表是否存在環,若是存在,則兩個鏈表相交,而檢測出來的依賴環入口即爲相交的第一個點。
2、若是兩個鏈表相交,那個兩個鏈表從相交點到鏈表結束都是相同的節點,咱們能夠先遍歷一個鏈表,直到尾部,再遍歷另一個鏈表,若是也能夠走到一樣的結尾點,則兩個鏈表相交。
這時咱們記下兩個鏈表length,再遍歷一次,長鏈表節點先出發前進(lengthMax-lengthMin)步,以後兩個鏈表同時前進,每次一步,相遇的第一點即爲兩個鏈表相交的第一個點。
Node* findCross(Node* head1,Node* head2) { if(head1==NULL||head2==NULL) return NULL; /*將第二個鏈表變成有環鏈表*/ Node* tail2=head2; while(tail2->next!=NULL) tail2=tail2->next; tail2->next = head2; Node* temp = findCircle(head1); if(temp!=NULL) return temp; else return NULL; }
bool isIntersect(pNode h1, pNode h2) { if(!h1 || !h2) return false; bool flag = false; pNode temp_h1 = h1; pNode temp_h2 = h2; //找到第一個鏈表的尾節點,將第二個鏈表掛在其後 while(temp_h1->next != NULL) temp_h1 = temp_h1->next; temp_h1->next = h2; do { temp_h2 = temp_h2->next; }while(temp_h2 && temp_h2 != h2); if(temp_h2 == h2) flag = true; //將鏈表恢復原樣 temp_h1->next = NULL; return flag; }
劍指offer面試題15:鏈表中的倒數第K個結點
今天先到底爲止,看一會操做系統的事。
明天繼續,明天一天把全部鏈表的題看完。