代码随想录Day03(补)

本文介绍了在LeetCode中的链表问题,包括移除元素、反转链表和设计链表,重点强调了双指针法的运用以及虚拟头结点在处理边界情况的优势。作者反思了打字错误对学习的影响,并分享了链表操作的关键在于指针和双指针法的应用。
摘要由CSDN通过智能技术生成

代码随想录Day03

今日任务

● 链表理论基础
● 203.移除链表元素
● 707.设计链表
● 206.反转链表

203 移除链表元素

LeetCode203
自己没想出的的原因就是没有使用双指针,没有这个思想,=
代码实现:

	//未采用虚拟头结点
    public ListNode removeElements(ListNode head, int target) {
        while (head != null && head.val == target) {
            head = head.next;
        }
        if (head == null) {
            return head;
        }
        ListNode pre = head;
        ListNode current = pre.next;
        while (current != null) {
            if (current.val == target) {
                pre.next = current.next;
            } else {
                pre = pre.next;
            }
            current = current.next;
        }
        return head;
    }

虚拟头结点

    public ListNode removeElements(ListNode head, int val) {
        ListNode virtualHead = new ListNode(-1, head);
        ListNode pre = virtualHead;
        ListNode current = virtualHead.next;
        while (current != null) {
            if (current.val == val) {
                pre.next = pre.next.next;
            } else {
                pre = pre.next;
            }
            current = current.next;
        }
        return virtualHead.next;
    }

虚拟头结点的优势在于头结点边界值特殊情况好处理

707.设计链表

LeetCode707
代码如下,这里只实现了未使用虚拟头结点的单链表,有时间试试双向链表

    static class MyLinkedList {

        ListNode head;

        public MyLinkedList() {

        }

        public int get(int index) {
            if (head == null) {
                return -1;
            }
            ListNode current = head;
            while (current != null && index > 0) {
                current = current.next;
                index--;
            }
            if (current == null) {
                return -1;
            }
            return current.val;
        }

        public void addAtHead(int val) {
            ListNode newHead = new ListNode(val);
            newHead.next = head;
            this.head = newHead;
        }

        public void addAtTail(int val) {
            if (head == null) {
                head = new ListNode(val);
                return;
            }
            ListNode current = head;
            while (current.next != null) {
                current = current.next;
            }
            current.next = new ListNode(val);
        }

        public void addAtIndex(int index, int val) {
            if (index == 0) {
                addAtHead(val);
                return;
            }
            if (head == null) {
                return;
            }
            ListNode pre = head;
            ListNode current = head.next;
            while (current != null && index > 1) {
                pre = current;
                current = current.next;
                index--;

            }
            //如果index还大于1,说明index长度大于链表长度
            if (index == 1) {
                pre.next = new ListNode(val, current);
            }
        }

        public void deleteAtIndex(int index) {
            if (head == null) {
                return;
            }
            if (index == 0) {
                head = head.next;
                return;
            }
            ListNode pre = head;
            ListNode current = head.next;
            while (current != null && index > 1) {
                pre = pre.next;
                current = current.next;
                index--;
            }
            if (current != null && index == 1) {
                pre.next = current.next;
            }

        }
    }

206.反转链表

LeetCode206
双指针法:
自己想的是把头结点一个一个指向下下个节点,然后将头结点的下一个节点放到最前,上次做题的时候也是这样想的。直接的反转使用temp保存临时节点的方式需要理解。

    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode currentHead = head;
        ListNode next = head.next;
        while (next != null) {
            head.next = next.next;
            next.next = currentHead;
            currentHead = next;
            next = head.next;
        }
        return currentHead;
    }

双指针-代码随想录版:

    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode temp = null;
        while (cur != null) {
            temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }

递归法,递归法就是将大问题拆解成一个个可以用同样方法解决的小问题,这个看了代码随想录的视频讲解后可以理解,从前往后的写法,这种写法是将双指针法“翻译”为递归法,思想是一样的


  public ListNode reverseList(ListNode head) {
        return reverse(null, head);
    }
    public ListNode reserve(ListNode pre, ListNode current) {
        if (current == null) {
            return pre;
        }
        ListNode temp = current.next;
        current.next = pre;
        return reserve(current, temp);
    }

leetcode官方给出的是从后往前的递归法,更符合一般情况下递归的场景,都是从后往前,但是万万是想不出来的,以后再理解吧~

总结

1.链表的重点是指针,链表题的重点是双指针法,一般是要保存当前节点和上一个节点
2.打字的时候错别字太多了,导致我写这几个字也很慢
今天先补昨天的,明天再补前天的

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值