《算法通关村第一关——链表经典问题之删除链表专题笔记》

文章介绍了LeetCode上的四个链表问题,包括删除所有值等于特定值的节点、删除链表的倒数第N个节点的两种方法以及删除链表中重复的元素。关键在于理解链表结构并巧妙地迭代更新节点。
摘要由CSDN通过智能技术生成

        一、LeetCode 203:给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val== val的节点,并返回新的头节点。

int[] a = {4, 4, 5, 1, 9, 9};
removeElements(nodeA, 9);

代码:

public static ListNode removeElements(ListNode head, int val) {
        ListNode dummyHead =new ListNode(0);
        dummyHead.next = head;
        ListNode temp = dummyHead;
        while(temp.next != null) {
            if (temp.next.val == val) {
                temp.next = temp.next.next;
            }else{
                temp = temp.next;
            }
        }
        return dummyHead.next;
    }

画图分析:
初始状态

 

前面都没9,往后走,都这停

进入while,开始处理,删除两个9

最后完成

 

 

 

 

二、LeetCode 19.删除链表的倒数第N个节点

        

        int[] a = {4, 4, 5, 1, 9, 9};

                

        result = removeNthFromEndByLength(nodeA, 3);

        方法1:首先从头节点开始对链表进行一次遍历,得到链表的长度L。随后我们再从头节点开始对链表进行一次遍历,当遍历到第L-n+1个节点时,它就是我们需要删除的节点。代码如下:
 

        

public static ListNode removeNthFromEndByLength(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode cur = dummy;
        int length = getLength(head);
        for (int i = 1;i < length-n+1;i++) {
            cur = cur.next;
        }

        cur.next = cur.next.next;
        ListNode ans = dummy.next;
        return ans;
    }

    public static int getLength(ListNode head) {
        int length = 0;
        while (head.next != null) {
            length++;
            head = head.next;
        }
        return length;
    }

画图分析:

        初始状态

 

        i从1开始,i<6-3+1=4结束

i = 1

i = 2

 

 i =3

for运算结束,cur的下一个节点就是要删的,最后从头遍历就行 

方法二:双指针。我们定义first和second两个指针,first先走N步,然后second再开始走,当first走到队尾的时候,second就是我们要的节点。代码如下:

 public static ListNode removeNthFromEndByTwoPoints(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode first = head;
        ListNode second = dummy;

        for (int i =0; i<n ; i++) {
            first = first.next;
        }
        while (first != null){
            first = first.next;
            second = second.next;
        }
        second.next = second.next.next;
        ListNode ans = dummy.next;
        return ans;
    }

画图分析:

初始状态

 

 for循环后:

 

 while后,找到要删的前一个节点,完成删除

 

三、LeetCode 83存在一个按升序排列的链表,请你删除所有重复的元素,使每个元素只出现一次。

int[] a = {1, 2, 3, 3, 4, 4, 5};
public static ListNode deleteDuplicate(ListNode head) {
        if (head == null){
            return head;
        }
        ListNode cur =  head;
        while (cur.next != null){
            if (cur.val == cur.next.val){
                cur.next = cur.next.next;
            }else {
                cur = cur.next;
            }
        }
        return head;
    }

画图分析:

初始状态:

cur走一步后,删除一个3.

往后走,删除一个4,完成

四、LeetCode 82存在一个按升序排列的链表,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中没有重复出现的数字。

 public static ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return head;
        }

        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode cur = dummy;
        while (cur.next != null && cur.next.next !=null) {
            if (cur.next.val == cur.next.next.val){
                int x = cur.next.val;
                while(cur.next != null && cur.next.val == x){
                    cur.next = cur.next.next;
                }
            }else {
                cur = cur.next;
            }
        }

        return dummy.next;
    }

画图分析:

初始状态:

cur走二步, 发现2个3,此时令x=3,后面的3全会被忽略。

此时cur下面的4又有2个,也要删除。删除完,第一个while的条件已不满足,结束

 

 

 

 总结:删除的核心:cur.next = cur.next.next。所以题都要主要循环的条件,仔细调试。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值