Java 八道經典面試題之鏈表題
第一題 移除鏈表元素
給你一個鏈表的頭節點 head 和一個整數 val ,請你刪除鏈表中所有滿足 Node.val == val 的節點,並返回 新的頭節點 。
輸入:head = [1,2,6,3,4,5,6], val = 6
輸出:[1,2,3,4,5]
這道題還是比較簡單的我們需要讓刪除的節點的前一個結點指向刪除節點的後一個就行。就比如cur.next==cur.next.next;。
class Solution { public ListNode removeElements(ListNode head, int val) { ListNode header=new ListNode(-1); header.next=head; ListNode cur =header; while(cur.next!=null){ if(cur.next.val==val){ cur.next=cur.next.next; }else{ cur=cur.next; } } return header.next; } }
第二題 反轉鏈表
給你單鏈表的頭節點 head ,請你反轉鏈表,並返回反轉後的鏈表。
輸入:head = [1,2,3,4,5]
輸出:[5,4,3,2,1]
這也是一個簡單題,我們還是先弄一個尾結點,因為鏈表的最後一個結點的下一個是一個null,這道題我們可以通過一次循環讓後一個結點的下一個結點指向前一個結點。
class Solution { public ListNode reverseList(ListNode head) { ListNode pre =null; ListNode cur=head; while(cur!=null){ ListNode next=cur.next; cur.next=pre; pre=cur; cur=next; } return pre; } }
第三題 鏈表的中心結點
給定一個頭結點為 head 的非空單鏈表,返回鏈表的中間結點。
如果有兩個中間結點,則返回第二個中間結點。
答:這個也是一個簡單題我們需要用到快慢指針,當快指針指完之後,慢的結點肯定是中點比如18 快的可以走9步每次走兩步走到18,慢的可以每次走一部走9步。剛好到中點。
class Solution { public ListNode middleNode(ListNode head) { ListNode p =head; ListNode q =head; while(q!=null&&q.next!=null){ q=q.next.next; p=p.next; } return p; } }
第四題 倒數第k個結點
輸入一個鏈表,輸出該鏈表中倒數第k個結點
輸入:
1,{1,2,3,4,5}
復制
返回值:
{5}
答:這道題也是一個簡單題,直接簡單粗暴的搞出來倒數第k個點的值就行;
public class Solution { public ListNode FindKthToTail(ListNode head,int k) { ListNode cur=head; ListNode pre=head; int count=0; int x=0; while(cur!=null){ cur=cur.next; count++; } if(k<0||k>count){ return null; } while(pre!=null){ if(x==count-k){ break; }else{ pre=pre.next; x++; } } return pre; } }
這道題寫的有點麻煩瞭,我們也可以用快慢指針做。一個指針走5步一個走4步。
public class Solution { public ListNode FindKthToTail(ListNode head,int k) { ListNode p=head; ListNode q=head; for(int i = 0; i < k; i++) { if (p != null) { p= p.next; } else { return null; } } while(p!=null){ p=p.next; q=q.next; } return q; } }
第五題 合並兩個有序鏈表
將兩個升序鏈表合並為一個新的 升序 鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。
輸入:l1 = [1,2,4], l2 = [1,3,4]
輸出:[1,1,2,3,4,4]
答:這道題考到瞭怎麼將兩個鏈表合並,我們需要將兩個鏈表從大到小合並起來。
class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode dummyHead = new ListNode(0); ListNode cur = dummyHead; while (l1 != null && l2 != null) { if (l1.val < l2.val) { cur.next = l1; cur = cur.next; l1 = l1.next; } else { cur.next = l2; cur = cur.next; l2 = l2.next; } } // 任一為空,直接連接另一條鏈表 if (l1 == null) { cur.next = l2; } else { cur.next = l1; } return dummyHead.next; } }
第六題 鏈表分割
現有一鏈表的頭指針 ListNode* pHead,給一定值x,編寫一段代碼將所有小於x的結點排在其餘結點之前,且不能改變原來的數據順序,返回重新排列後的鏈表的頭指針。
輸入:l1 = [1,2,1,3,2] 3
輸出:[1,2,1,2,3]
這道題比較難瞭需要我們創建兩個鏈表,一個數大與等於x的鏈表,另一個數小於x的鏈表。然後讓上一個鏈表的下一個尾結點指向下一個結點的尾巴結點。
這裡我們需要用到如何將兩個鏈表合並成一個鏈表。
做題的時候先想怎麼做然後在動手!
public class Partition { public ListNode partition(ListNode pHead, int x) { if(pHead == null || pHead.next == null) { return pHead; } ListNode newHead = new ListNode(0); ListNode flagHead = new ListNode(0); ListNode newh = newHead; ListNode flagh = flagHead; while(pHead != null){ if(pHead.val < x){ newh.next = new ListNode(pHead.val); newh = newh.next; }else{ flagh.next = new ListNode(pHead.val); flagh = flagh.next; } pHead = pHead.next; } newh.next = flagHead.next; return newHead.next; } }
第七題 判斷是否回文
對於一個鏈表,請設計一個時間復雜度為O(n),額外空間復雜度為O(1)的算法,判斷其是否為回文結構。
給定一個鏈表的頭指針A,請返回一個bool值,代表其是否為回文結構。保證鏈表長度小於等於900。
1->2->2->1
返回:true
public class PalindromeList { public boolean chkPalindrome(ListNode head) { // write code here ListNode fast=head; ListNode slow=head; while(fast!=null && fast.next!=null) { fast = fast.next.next; slow = slow.next; } ListNode cur=slow.next; while(cur!=null){ ListNode curNext=cur.next; cur.next=slow; slow=cur; cur=curNext; } //3.一個從前往後,一個從後往前 如果相遇,則證明回文 while(head!=slow){ if(head.val!=slow.val){//先判斷值是否相等 return false; } if(head.next==slow){//偶數情況下 return true; } head=head.next; slow=slow.next; } return true; }
第八題 相交鏈表
給你兩個單鏈表的頭節點 headA 和 headB ,請你找出並返回兩個單鏈表相交的起始節點。如果兩個鏈表不存在相交節點,返回 null 。
可以用笨方法就是計算出來每個鏈表的個數然後讓多的先走。
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) { return null; } ListNode last = headB; while (last.next != null) { last = last.next; } last.next = headB; ListNode fast = headA; ListNode slow = headA; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { slow = headA; while (slow != fast) { slow = slow.next; fast = fast.next; } last.next = null; return fast; } } last.next = null; return null; } }
到此這篇關於Java 八道經典面試題之鏈表題的文章就介紹到這瞭,更多相關Java 鏈表題內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- C++數據結構之鏈表詳解
- 教你如何輕松學會Java快慢指針法
- C++實現LeetCode(160.求兩個鏈表的交點)
- C++實現LeetCode(148.鏈表排序)
- C++解決輸出鏈表中倒數k個結點的問題