代码随想录算法训练营第三天| 203. 移除链表元素、707. 设计链表、206. 反转链表

203

203

image-20230317231930344

solution 1:

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //虚拟节点
        ListNode dummyNode = new ListNode(val-1);
        dummyNode.next = head;
        ListNode p = dummyNode;//一定不为null
        while(p.next!=null){//去探测next是否为null
            if(p.next.val == val){
                p.next = p.next.next;
            }else{
                p = p.next;
            }
        }
        return dummyNode.next;
    }
}

solution 2:

分类讨论:处理头节点是val;处理不是头节点是val。

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        while(head != null && head.val == val){
            head = head.next;//一直移动,直到头节点不是val的节点
        }

        if(head == null){
            return null;
        }

        ListNode p = head;
        while(p.next!=null){
            if(p.next.val == val){
                p.next = p.next.next;
            }else{
                p = p.next;
            }
        }

        return head;
    }
}

参考题解:

https://leetcode.cn/problems/remove-linked-list-elements/solution/203yi-chu-lian-biao-yuan-su-by-lewis-dxstabdzew/

等有空了,去思考一下递归的做法。

707

707

image-20230317232618667

单链表实现:

注意边界情况。

class ListNode {//单链表
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val) {
        this.val=val;
    }
}

class MyLinkedList {
    //size存储链表元素的个数
    int size;
    //虚拟头结点
    ListNode head; // 这里定义的头结点 是一个虚拟头结点,而不是真正的链表头结点

    //初始化链表
    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
    }
    
    public int get(int index) {
        //index是从0开始的,第0个节点就是头结点
        //防止越界
        if(index < 0 || index >= size){
            return -1;
        }

        ListNode p = head;
        for(int i=0;i<=index;i++){//一共index次
            p = p.next;
        }

        return p.val;
    }
    
    //在下标为0的位置上插入节点
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    //在下标为sieze的位置上插入节点
    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++;

        //遍历到index-1
        ListNode p = head;
        for(int i=0;i<=index-1;i++){
            p = p.next;
        }
        ListNode newNode = new ListNode(val);
        newNode.next = p.next;
        p.next = newNode;
    }
    
    public void deleteAtIndex(int index) {
        if (index < 0 || index >= size) {
            return;
        }

        size--;

        if (index == 0) {
            head = head.next;
	        return;
        }

        //遍历到index-1
        ListNode p = head;
        for(int i=0;i<=index-1;i++){
            p = p.next;
        }
        p.next = p.next.next;
    }
}

双链表情况:

class ListNode {//双链表
    int val;
    ListNode next,prev;
    ListNode(){}
    ListNode(int val) {
        this.val=val;
    }
}

class MyLinkedList {
    //size存储链表元素的个数
    int size;
    //虚拟头结点和尾节点
    //尾节点就是最后一个节点
    ListNode head,tail; 

    //初始化链表
    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
        tail = new ListNode(0);//?
        head.next = tail;
        tail.prev = head;
    }
    
    public int get(int index) {
        //判断index是否有效
        if(index<0 || index>=size){
            return -1;
        }
        ListNode p = head;
        if(index >= size/2){
            p = tail;
            for(int i=0;i<size-index;i++){//需要从后往前遍历size-1-index+1=size-index个
                p = p.prev;
            }

        }else{
            for(int i=0;i<=index;i++){
                p = p.next;
            }
        }
        return p.val;
    }
    
    //在下标为0的位置上插入节点
    public void addAtHead(int val) {
        addAtIndex(0,val);
        
    }
    
    //在下标为sieze的位置上插入节点
    public void addAtTail(int val) {
        addAtIndex(size,val);
    }
    
    public void addAtIndex(int index, int val) {
        //index大于链表长度
        if(index > size){
            return;
        }
        //index小于0
        if(index < 0){
            index = 0;
        }
        size++;
        //找到前驱
        ListNode pre = this.head;
        for(int i=0; i<=index-1; i++){
            pre = pre.next;
        }
        //新建结点
        ListNode newNode = new ListNode(val);
        newNode.next = pre.next;
        pre.next.prev = newNode;
        newNode.prev = pre;
        pre.next = newNode;
    }
    
    public void deleteAtIndex(int index) {
        //判断索引是否有效
        if(index<0 || index>=size){
            return;
        }
        //删除操作
        size--;
        ListNode pre = this.head;
        for(int i=0; i<=index-1; i++){
            pre = pre.next;
        }
        pre.next.next.prev = pre;
        pre.next = pre.next.next;
    }
}

206

206

image-20230317233005870

class Solution {
    public ListNode reverseList(ListNode head) {
        //头插法
        if(head==null){
            return null;
        }

        ListNode p = head;
        ListNode resultHead = null;
        while(p != null){
            System.out.println(p.val);
            ListNode q = new ListNode(p.val);//注意
            q.next = resultHead;
            resultHead = q;
            p = p.next;
            System.out.println(p);//debug
        }
        return resultHead;
    }
}

之前写成q.next = p,就会出现逻辑错误。

image-20230317234246810

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值