Day3| 203.移除链表元素,707.设计链表,206.反转链表

203.移除链表元素代码随想录

/**
 * 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) {
        ListNode dh = head , p = dh;//dh初始化时没有接上链表
        while(p != null){//出现空指针异常,说明操作了某些空指针,要么越界要么对同一对象使用了多个指针
            if(p.next.val == val){
                p.next = p.next.next;
            }else{
                p = p.next;
            }
        }
        return dh.next;
    }
}

//修改后代码
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dh = new ListNode();
        dh.next = head;
        ListNode p = dh;
        while(p.next != null){
            if(p.next.val == val){
                p.next = p.next.next;
            }else{
                p = p.next;
            }
        }
        return dh.next;
    }
}

 707.设计链表代码随想录

一、想一下目标位置是由哪一个位置变化而来,假如目标位置是最后一个节点,由倒数第二个节点前进得来,那么这个过程就应当是最后一次循环的语句,其执行条件即是最后一次执行条件,其下一个过程的执行条件即是终止条件,一般取终止条件的否定,感觉这些条件判断要多见识积累。

二、应用于get节点和增删节点寻找其前一个节点的过程

 出错程序一:

class Node {
    int val;
    Node next;
    Node(){}
    Node(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    int size;
    Node head;

    public MyLinkedList() {
        size = 0;
        head = new Node(0);
    }
 
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        Node p = head;
        while(index != 0){
            p = p.next;
            index--;
        }
        return p.val;
        
    }
    
    public void addAtHead(int val) {
        // Node dummy = new Node();
        // Node x = new Node(val);
        // x.next = dummy.next;
        // dummy.next = x;
        addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        // Node x = new Node(val);
        // Node p = head;
        // while(p.next != null){
        //     p = p.next;
        // }
        // p.next = x;
        addAtIndex(size,val);
    }
    
    // public void addAtIndex(int index, int val) {
    //     if(index > size){
    //         return;
    //     }
    //     if(index == 0){
    //         index = 0;
    //     }
    //     Node dummy = new Node();
    //     dummy.next = head;
    //     Node p = dummy;
    //     //while(index != 0)
    //     for(int i = 0; i < index; i++){
    //         p = p.next; 
    //     }
    //         Node x = new Node(val);
    //         x.next = p.next;
    //         p.next = x;
    //         size++;
        
        
    // }
    public void addAtIndex(int index, int val) {
        if (index > size) {
            return;
        }
        if (index < 0) {
            index = 0;
        }
        size++;
        //找到要插入节点的前驱
        Node dummy = new Node();
        dummy.next = head;
        Node pred = dummy;
        for (int i = 0; i < index; i++) {
            pred = pred.next;
        }
        Node toAdd = new Node(val);
        toAdd.next = pred.next;
        pred.next = toAdd;
    }
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        Node dummy = new Node();
        dummy.next = head;
        Node p = dummy;
        while(index != 0){
            p = p.next;
            index--;
        }
        p.next = p.next.next;


    }
    // public int getsize(){
    //     Node p = head;
    //     int count = 0;
    //     while(p != null){
    //         count++;
    //         p = p.next;
    //     }
    //     return count;
    // }
 
    // public boolean isIndexValid(index){
    //     int size = getsize();
    //     if(index >= 0 && index < size - 1){
    //         return true;
    //     }else{
    //         return true;
    //         }
        
    // }
}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

出错程序二: 

class Node {
    int val;
    Node next;
    Node(){}
    Node(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    int size;
    Node head;
    public MyLinkedList() {
        size = 0;
    }
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        Node p = head;
        while(index != 0){
            p = p.next;
            index--;
        }
        return p.val;

    }
    
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(size,val);
    }

    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        Node dummy = new Node();
        dummy.next = head;
        Node p = dummy;
        while(index != 0){
            p = p.next; 
            index--;
        }
            Node x = new Node(val);
            x.next = p.next;
            p.next = x;
            size++;
    }

    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        Node dummy = new Node();
        dummy.next = head;
        Node p = dummy;
        while(index != 0){
            p = p.next;
            index--;
        }
        p.next = p.next.next;
    }

}

没出错 

class Node {
    int val;
    Node next;
    Node(){}
    Node(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    int size;
    Node dummyhead;
    public MyLinkedList() {
        size = 0;
        dummyhead = new Node(0);
    }
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        Node p = dummyhead;
        while((index+1) != 0){
            p = p.next;
            index--;
        }
        return p.val;

    }
    
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(size,val);
    }

    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        size++;
        Node p = dummyhead;
        for(int i = 0; i<index;i++){
            p = p.next; 
            
        }
            Node x = new Node(val);
            x.next = p.next;
            p.next = x;
            
    }

    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        
        Node p = dummyhead;
        while(index != 0){
            p = p.next;
            index--;
        }
        p.next = p.next.next;
        size--;
    }

}

出错程序三:

class Node {
    int val;
    Node next;
    Node(){}
    Node(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    int size;
    Node dummyhead;
    public MyLinkedList() {
        size = 0;
        dummyhead = new Node(0);
    }
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        Node p = dummyhead;
        while((index+1) != 0){
            p = p.next;
            index--;
        }
        return p.val;

    }
    
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(size,val);
    }

    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        size++;
        Node p = dummyhead;
        for(int i = 0; i<index;i++){
            p = p.next; 
            
        }
            Node x = new Node(val);
            x.next = p.next;
            p.next = x;
            
    }

    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        
        Node p = dummyhead;
        while(index != 0){
            p = p.next;
            index--;
        }
        p.next = p.next.next;
        size--;
    }

}

没出错 

class Node {
    int val;
    Node next;
    Node(){}
    Node(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    int size;
    Node dummyhead;
    public MyLinkedList() {
        size = 0;
        dummyhead = new Node(0);
    }
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        Node p = dummyhead;
        while((index+1) != 0){
            p = p.next;
            index--;
        }
        return p.val;

    }
    
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        addAtIndex(size,val);
    }

    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        size++;
        Node p = dummyhead;
        for(int i = 0; i<index;i++){
            p = p.next; 
            
        }
            Node x = new Node(val);
            x.next = p.next;
            p.next = x;
            
    }

    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        
        Node p = dummyhead;
        while(index != 0){
            p = p.next;
            index--;
        }
        p.next = p.next.next;
        size--;
    }

}

/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

我很执着于用head放入链表,在函数中添加dummy再操作,力扣判题时是直接在dummyhead后加新元素

head不算是第0个节点wc。head本身就是虚拟头结点,哨兵节点

size更新非常重要,会决定index约不越界,若删除了节点没更新size--,下一次删除index即使越界自己的判定语句也不会抛异常,而是执行while循环导致p越界去操作空指针。

总结,之前很多次提交没过

原因一:0号节点是从head.next开始的,

原因二:size没更新,导致index异常时还会走while循环,导致p越界操作了空指针。

检查时,重心都放在p有没有走到正确的位置上的代码逻辑有误问题,这个过程自己默认传入while的index值是合法的,实际上size的没更新,造成了越界,耗费了很多时间。一开始我的p从head前一个dummy开始走,理论上,到达的位置更靠前,也出现了p越界,现在想来原因大概还是出现在没有size--,以致index越界没被检测出来进入了while。

最后修改版本:

class Node {
    int val;
    Node next;
    Node(){}
    Node(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    int size;
    Node head;

    public MyLinkedList() {
        size = 0;
        head = new Node(0);
    }
 
    
    public int get(int index) {
        if(index < 0 || index >= size){
            return -1;
        }
        Node p = head.next;
        while(index != 0){
            p = p.next;
            index--;
        }
        return p.val;
        
    }
    
    public void addAtHead(int val) {
        Node x = new Node(val);
        x.next = head.next;
        head.next = x;
        size++;
        //addAtIndex(0,val);
    }
    
    public void addAtTail(int val) {
        Node x = new Node(val);
        Node p = head;
        while(p.next != null){
            p = p.next;
        }
        p.next = x;
        size++;
        //addAtIndex(size,val);
    }
    
    public void addAtIndex(int index, int val) {
        if(index > size){
            return;
        }
        if(index < 0){
            index = 0;
        }
        
        Node p = head;
        while(index != 0){
            p = p.next; 
            index--;//漏了,死循环,p越界空指针了,重心都放在走了多少步,却忘了更新index
        }
            Node x = new Node(val);
            x.next = p.next;
            p.next = x;
            size++;
        
        
    }

    
    public void deleteAtIndex(int index) {
        if(index < 0 || index >= size){
            return;
        }
        
        Node p = head;
        while(index != 0){
            p = p.next;
            index--;
        }
        p.next = p.next.next;
        size--;//漏了,导致第二次删节点时即使index越界了也能进入循环使p操作了空指针
    }

}

 206.反转链表代码随想录

双指针:

/**
 * 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) {
        ListNode p = head , p0 = null;
        while(p != null){
        ListNode temp = new ListNode();
        temp = p.next;
        p.next = p0;
        p0 = p;
        p = temp;//对应关系: p每一次前进都对应一次反转操作,最后一次情形:p在tail处反转tail后并前进到null,终止状态是p == tail时执行,p == null不执行
        }
        return p0;//直接把反转后的第一个节点当成头节点就好,虽然其有值,但题目要求就是单纯反转操作,不能在原链表上再接一个无值的head
    }
}

递归:

 递归太抽象了,脑子转不过来,有空再看,

感觉跟循环有对应的地方,有正着迭代下去的操作,一层一层套进去,这题的循环也是正着迭代下去的,暂且先掌握双指针做法。

双指针还能画个链表图比划比划较快地写出来,递归先留着。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值