<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
每個題目後面有放對應題目的OJ連結,大家可以先了解一下解題思路,然後自己先去做一下。
刪除連結串列中等於給定值val的所有節點。【OJ連結】
定義兩個指標prev、cur,cur指向頭節點的下一個節點,prev始終指向cur的前一個結點(方便刪除節點)。通過cur指標去遍歷連結串列,和val值比較,相同就刪除這個節點。最後再來比較頭節點。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode removeElements(ListNode head, int val) { if(head==null){ return null; } ListNode prev=head; ListNode cur=head.next; while(cur!=null){ if(cur.val==val){ prev.next=cur.next; cur=cur.next; }else{ prev=cur; cur=cur.next; } } if(head.val==val){ head=head.next; } return head; } }
反轉一個連結串列。【OJ連結】
在遍歷連結串列時,將當前節點的 指標改為指向前一個節點。由於節點沒有參照其前一個節點,因此必須事先儲存其前一個節點。在更改參照之前,還需要儲存後一個節點。最後返回新的頭參照。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode reverseList(ListNode head) { if(head==null){ return null; } ListNode cur=head.next; head.next=null; while(cur!=null){ ListNode curNext=cur.next; cur.next=head; head=cur; cur=curNext; } return head; } }
給定一個帶有頭節點的非空單連結串列,返回連結串列的中間節點。如果有兩個中間節點,則返回第二個中間節點。【OJ連結】
我們可以定義兩個快慢指標(fast、slow),都指向頭節點。快指標每次走兩步,慢指標每次走一步。連結串列有偶數個節點時,fast=null時slow為中間節點;連結串列有奇數個節點時,fast.next=null時slow為中間節點。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode middleNode(ListNode head) { if(head==null){ return null; } ListNode slow=head; ListNode fast=head; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; } return slow; } }
輸入一個連結串列,返回該連結串列中倒數第K個節點。【OJ連結】
這個題和找中間節點的思路相似。定義兩個指標(fast、slow)。在K合理的前提下,我們可以讓快指標先走K-1步,然後快慢指標同時向後走,當fast到達連結串列結尾時,slow就指向倒數第K個節點。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if(k<=0||head==null){ return null; } ListNode fast=head; ListNode slow=head; while(k-1>0){ if(fast.next==null){ return null; } fast=fast.next; //先讓快節點走k-1步 k--; } while(fast.next!=null){ fast=fast.next; slow=slow.next; } return slow; } }
將兩個有序連結串列合併為一個有序連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。【OJ連結】
解這個題,需要定義虛假節點來充當新連結串列的頭節點。通過兩個連結串列的頭節點去遍歷兩個節點,去比較兩個連結串列對應節點的值,將值小的節點連線到新連結串列的後面,知道兩個連結串列遍歷完,當其中一個連結串列為空時,直接將另一個連結串列連線到新連結串列後面即可。
class Solution { public ListNode mergeTwoLists(ListNode list1, ListNode list2) { if(list1==null){ return list2; } if(list2==null){ return list1; } //建立虛擬節點,充當新連結串列的頭節點,值不代表任何意義 ListNode node=new ListNode(-1); ListNode cur=node; while(list1!=null&&list2!=null){ if(list1.val<list2.val){ cur.next=list1; list1=list1.next; }else{ cur.next=list2; list2=list2.next; } cur=cur.next; } if(list1==null){ cur.next=list2; }else{ cur.next=list1; } return node.next; } }
將一個連結串列按照給定值X劃分為兩部分,所有小於X的節點排在大於或等於X的節點之前。不改變節點原來的順序。【OJ連結】
首先我們需要定義四個指標(bs、be、as、ae)分別表示小於X部分連結串列的頭節點和尾節點、大於X部分連結串列的頭節點和尾節點。通過頭節點遍歷連結串列,將連結串列分為兩部分。最後將兩個連結串列連線起來即可。需要特別注意,當小於X部分連結串列不為空時,我們需要手動將ae.next置為空。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Partition { public ListNode partition(ListNode pHead, int x) { if(pHead==null){ return null; } ListNode bs=null; ListNode be=null; ListNode as=null; ListNode ae=null; ListNode cur=pHead; while(cur!=null){ if(cur.val<x){ if(bs==null){ bs=cur; be=cur; }else{ be.next=cur; be=cur; } }else{ if(as==null){ as=cur; ae=cur; }else{ ae.next=cur; ae=cur; } } cur=cur.next; } if(bs==null){ return as; //如果小於X部分為空,則直接返回大於X部分即可。此時ae.next一定為null } be.next=as;//否則連線小於X和大於X部分 if(as!=null){ ae.next=null; //當小於X部分不為空時,ae.next可能不為null,需要手動置為null } return bs; } }
判斷連結串列是不是迴文連結串列。【OJ連結】
首先我們需要找到連結串列的中間節點,然後將後半段連結串列反轉。最後通過兩邊來逐步比較即可。特別注意,當連結串列結點個數為偶數時,因為中間節點的緣故,兩邊遍歷時,無法相遇,需要特殊處理。
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class PalindromeList { public boolean chkPalindrome(ListNode A) { if(A==null){ return false; } if(A.next==null){ return true; } //求連結串列的中間節點 ListNode slow=A; ListNode fast=A; 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; } //判斷迴文連結串列 while(slow!=A){ if(slow.val!=A.val){ return false; } if(A.next==slow){ return true; } slow=slow.next; A=A.next; } return true; } }
輸入兩個連結串列,輸出兩個連結串列的第一個公共節點。沒有返回NULL。【OJ連結】
兩個連結串列相交呈現Y字型。那麼兩個連結串列長度的差肯定是未相交前兩個連結串列節點的差。我們需要求出兩個連結串列的長度。定義兩個指標(pl、ps),讓pl指向長的連結串列,ps指向短的連結串列。求出兩個連結串列的長度差len。讓pl想走len步。這樣兩個連結串列的剩餘長度就相同。此時兩個指標同時遍歷連個連結串列,如果其指向一致,則兩個連結串列相交,否則,兩個連結串列不相交。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { //求連結串列長度 public int len(ListNode head){ int len=0; while(head!=null){ head=head.next; len++; } return len; } public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if(headA==null||headB==null){ return null; } ListNode pl=headA; ListNode ps=headB; int lenA=len(headA); int lenB=len(headB); int len=lenA-lenB; if(len<0){ //pl指向長的連結串列,ps指向短的連結串列 pl=headB; ps=headA; len=-len; } while(len--!=0){ pl=pl.next; } while(pl!=null){ if(pl==ps){ return pl; } pl=pl.next; ps=ps.next; } return null; } }
判斷連結串列中是否有環。【OJ連結】
還是快慢指標。慢指標一次走一步,快指標一次走兩步。兩個指標從連結串列起始位置開始執行。如果連結串列帶環則一定會在環中相遇,否則快指標率先走到連結串列的末尾。
【拓展】
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { if(head==null||head.next==null){ return false;//連結串列為空或者只有一個節點時,沒有環 } ListNode slow=head; ListNode fast=head; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; if(fast==slow){ return true; //如果快慢節點可以相遇,表示連結串列有環 } } return false; } }
給定一個連結串列,判斷連結串列是否有環並返回入環的節點。如果沒有環,返回NULL。【OJ連結】
讓一個指標從連結串列的其實在位置開始遍歷,同時另一個指標從上題中兩隻真相與的位置開始走,兩個指標再次相遇時的位置肯定為環的入口
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { //判斷連結串列是否有環,並返回第一次快慢節點相交的位置 public ListNode hasCycle(ListNode head){ if(head==null||head.next==null){ return null; } ListNode slow=head; ListNode fast=head; while(fast!=null&&fast.next!=null){ slow=slow.next; fast=fast.next.next; if(slow==fast){ return slow; } } return null; } //當返回的結點與頭節點再次相交時,為環的入口 public ListNode detectCycle(ListNode head) { ListNode node=hasCycle(head); if(node==null){ return null; }else{ while(head!=node){ head=head.next; node=node.next; } } return head; } }
到此這篇關於Java 連結串列實戰真題訓練的文章就介紹到這了,更多相關Java 連結串列內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45