链表删除结点合集
力扣83:
思路:利用雙指針,fast遍歷鏈表,slow指向所有去掉重復元素的鏈表,因為是1223->123,所以第一個結點一定保留,不用創建新的結點,slow和fast可以直接指向head。
public ListNode deleteDuplicates(ListNode head){if(head==null) return null;ListNode slow=head;ListNode fast=head;while(fast!=null){if(fast.val!=slow.val){slow.next=fast;slow=slow.next;}fast=fast.next;}slow.next=null;return head;}優化:實際上不需要雙指針
public ListNode deleteDuplicates(ListNode head){if(head==null) return null;ListNode cur=head;while(cur!=null&&cur.next!=null){if(cur.val==cur.next.val){cur.next=cur.next.next;}else{cur=cur.next;}}return head;}力扣82:
思路:和上題不同在于重復的元素一個都不留,1223->13,為了防止第一個元素就是重復元素,需要創建新結點,同樣是雙指針,slow指向新結點,fast指向head。
方法一:哈希表
public ListNode deleteDuplicates(ListNode head){if(head==null||head.next==null) return head;HashMap<Integer,Integer> map=new HashMap<>();ListNode node=head;while(node!=null){if(map.containsKey(node.val)){map.put(node.val,map.get(node.val)+1);}else {map.put(node.val,1);}node=node.next;}ArrayList<Integer> arr=new ArrayList<>();for(Integer k:map.keySet()){if(map.get(k)==1){arr.add(k);}}Collections.sort(arr);ListNode res=new ListNode(0);ListNode temp=res;for(Integer i:arr){ListNode p=new ListNode(i);temp.next=p;temp=temp.next;}return res.next;}方法二:雙指針
public ListNode deleteDuplicates(ListNode head){if(head==null||head.next==null) return head;ListNode temp=new ListNode();ListNode slow=temp;ListNode fast=head;temp.next=head;//這一步容易被忽略,因為要比較slow.next==fast,如果fast是鏈表第一個結點,要讓slow.next!=null;while(fast!=null){while(fast.next!=null&&fast.val==fast.next.val){fast=fast.next;}//這時fast指向重復結點的最后一個if(slow.next==fast){slow=slow.next;}else {slow.next=fast.next;//如果fast是鏈表最后一個結點,slow=null,因此不用執行slow.next=null;}fast=fast.next;}return temp.next;} public static ListNode deleteDuplicates(ListNode head){if(head==null||head.next==null) return head;ListNode res=new ListNode(0);res.next=head;ListNode a=res;ListNode b=head.next;while(b!=null){if(a.next.val!=b.val){a=a.next;b=b.next;}else{while(b!=null&&a.next.val==b.val){b=b.next;}a.next=b;b=b==null?null:b.next;}}return res.next;}劍指18:刪除鏈表的結點
public ListNode deleteNode(ListNode head, int val){if(head.val==val) return head.next;//一般如果需要判斷頭結點需要創建臨時結點,但是這里首先判斷了所以可以直接令slow=head;ListNode slow=head;ListNode fast=head.next;while(fast!=null&&fast.val!=val){slow.next=fast;slow=slow.next;fast=fast.next;}if(fast!=null){slow.next=fast.next;}return head;}相似題:力扣237
思路:將需要刪除的結點的下一個復制,然后刪除的是下一個結點
public void deleteNode(ListNode node) {node.val=node.next.val;node.next=node.next.next;}力扣19:刪除鏈表的倒數第K個結點
public ListNode removeNthFromEnd(ListNode head, int n){ListNode dummy=new ListNode(0);ListNode pre=dummy;dummy.next=head;ListNode fast=head;ListNode slow=head;for(int i=0;i<n;i++){fast=fast.next;}while(fast!=null){slow=slow.next;pre=pre.next;fast=fast.next;}pre.next=slow.next;return dummy.next;}總結
- 上一篇: 汽车安全标准ISO-26262以及等级A
- 下一篇: 当人工智能教学走进小学课堂之时