Day3_Linkedlist, Leetcode 203, 707 and 206

Leetcode 203:

https://leetcode.com/problems/remove-linked-list-elements/description/

题目的第一想法:

单向链表的删除情况分为首中2种。在首的情况下,需要一直删除首位node,变更head指向的位置。在中的情况下我们需要一个pre来跟踪前一位Node,做pre指向current.next。同时需要注意的是在链表的size可以为0。于是就有三种情况需要被解决:1,当链表的本身size为0;2,当链表头部的node需要被删除;3,当链表头部的node被删除后依旧有更多的(>=2)的node可以被遍历。当完成这三步时,这个问题便可以被解决。

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head == null){//when size == 0
            return null;
        }
        while(head != null && head.val == val){// removing the head node
            ListNode temp = head.next;
            head.next = null;
            head = temp;
        }
        if(head != null && head.next != null){// if there is still more nodes to traverse
            ListNode pre = head;
            ListNode current = head.next;
            while(current != null){
                if(current.val == val){// if a node is found to be deleted 
                    pre.next = current.next;
                    current = current.next;
                }else{
                    pre = current;// traverse
                    current = current.next;
                }
            }
        }
        return head;
    }
}

Leetcode 707:

https://leetcode.com/problems/design-linked-list/description/

题目的第一想法:

这是道考验基本功的题,如果对于链表的数据结构比较熟悉的话做出这道题就没什么大问题。我的第一想法是最一个双向链表,这样的话对删除Node的操作会比较友好。但在增加Node上增添了很多麻烦。还有一点是应该增加Sentinel Node,这样的话对与整体的写法会简洁方便许多。但我的初想法因为对sentinel node的下意识恐惧就没有加上,导致之后在debug上费了不少时间。以下是我的第一版通过的code。时间复杂度不好,具体原因等我研究一下再更新。

class ListNode {
    public int val;
    public ListNode next;
    public ListNode pre;

    public ListNode(int val){
        this.val = val;
        next = null;
        pre = null;
    }
}

class MyLinkedList {
    ListNode head;
    ListNode tail;
    int size;

    public MyLinkedList() {
        head = null;
        tail = null;
        int size = 0;
    }
    
    public int get(int index) {
        ListNode current = head;
        if(index >= size){
            return -1;
        }
        for(int i = 0; i < index; i++){
            current = current.next;
        }
        return current.val;
    }
    
    public void addAtHead(int val) {
        ListNode temp = new ListNode(val);
        temp.next = head;
        temp.pre = null;
        if(size != 0){
            head.pre = temp;
        }else{
            tail = temp;
        }
        head = temp;
        size++;
    }
    
    public void addAtTail(int val) {
        ListNode temp = new ListNode(val);
        temp.pre = tail;
        if(size != 0){
            tail.next = temp;
        }else{
            head = temp;
        }
        tail = temp;
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        System.out.println(index + " " + val);
        if(index <= size){
            if(size == 0){
                ListNode temp = new ListNode(val);
                head = temp;
                tail = temp;
                size++;
            }else if(index == size){
                this.addAtTail(val);
            }else if(index == 0){
                this.addAtHead(val);
            }else{
                ListNode current = head;
                for(int i = 0; i < index; i++){
                    current = current.next;
                }
                ListNode temp = new ListNode(val);
                System.out.println(current.val);
                temp.next = current;
                temp.pre = current.pre;
                current.pre.next = temp;
                current.pre = temp;
                size++;
            }
        }
    }
    
    public void deleteAtIndex(int index) {
        if(index < size){
            ListNode current = head;
            if(index == 0){
                ListNode temp = current.next;
                if(size == 1){
                    head = null;
                }else{
                    temp.pre = null;
                    current.next = null;
                    head = temp;
                }
            }else if(index == size - 1){
                ListNode temp = tail.pre;
                tail.pre = null;
                temp.next = null;
                tail = temp;
            }else{
                for(int i = 0; i < index; i++){
                current = current.next;
                }
                ListNode temp = current.pre;
                temp.next = current.next;
                current.next.pre = temp;
            }
            size--;
        }
    }
}

Leetcode 206:

https://leetcode.com/problems/reverse-linked-list/description/

题目的第一想法:

这道题和删除的根本思想差不多,都是依靠pre和current做一个遍历来更改链表的方向。需要注意的是current和pre变更的循序。需先改pre为current再改current为temp(current.next)。除此之外,这道题观感上也应可以那recurssion来解决。等我有时间再尝试下新的解法。

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode current = head.next;
        ListNode pre = head;
        pre.next = null;
        while(current != null){
            ListNode temp = current.next;
            current.next = pre;
            pre = current;
            current = temp;
        }
        head = pre;
        return head;
    }
}

看完代码随想录之后的想法:

。。。

自己实现过程中遇到哪些困难:

这道题倒是没遇到什么特别的困难

今日收获,记录一下自己的学习时长:

复习了链表的相关操作和知识。明天需要再把python版本的答案附写一遍,来熟悉python语法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值