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

第三天| 203.移除链表元素707.设计链表206.反转链表
/**
 * 2023/12/29 第三天 T1
 * 203.移除链表元素
 */
public ListNode removeElements(ListNode head, int val) {
        while (head != null && head.val == val){//删除开头等于val的节点
            head = head.next;
        }
        if (head == null) return head; //坑!!这里一定要判断是否为空,不然p.next head.next 就是空指针异常!!
        ListNode p = head;//用p去遍历链表,并删除val值的节点(head始终指向第一个节点)
        while (p.next != null){
            if (p.next.val == val){
                p.next = p.next.next; //p的下一个节点的值等于val 删除即可
            } else {
                p = p.next; //p的下一个节点的值不等于val p就右移
            }
        }
        return head;
    }
  • 写出来了,但是有个小坑。

  • 没有判断head.next是否为null,导致空指针异常。

  • 收获:复习了链表相关操作,1h。

/**
 * 2023/12/29 第三天 T2
 * 707.设计链表
 */
class ListNode {
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val) {
        this.val=val;
    }
}
class MyLinkedList {//单链表 默认节点下标从0开始(不包括头节点)!!!
    int size;
    ListNode head; //设置头节点是为了方便插入时的统一 使得在所有插入都采用头插法(包括尾部插入,此时需要插入的节点的前一个节点就是链表最后一个元素)

    public MyLinkedList() {
        size = 0;//初始化链表长度
        head = new ListNode(0); //初始化头节点
    }

    public int get(int index) { //get
        if (index < 0 || index >= size) return -1;
        ListNode p = head;
        for (int i =0; i <= index; i++){
            p = p.next;
        }
        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) { //add
        if (index > size) return; //大于size默认插入失败
        if(index < 0) index = 0; //小于0默认index为0 即在头部插入(插入到头节点之后)
        size++; //链表长度+1
        ListNode s = new ListNode(val);
        ListNode p = head;
        for (int i = 0; i < index; i++){//找到插入元素的前驱节点
            p = p.next;
        }
        //头插法
        s.next = p.next;
        p.next = s;
    }

    public void deleteAtIndex(int index) { //delete
        if (index < 0 || index >= size) return; //注意等于size的情况 会报空指针异常,因此要排除。
        size--; //链表长度-1
        ListNode p = head;
        for (int i = 0; i < index; i++){ //找到删除元素的前驱节点
            p = p.next;
        }
        p.next = p.next.next;
    }

}

//双链表写法 (待补充...)
  • 自己写还是很多小错误。
  • 设置头节点head统一插入(类似使用头插法构建链表的方式)和删除的方式设置size便于下标相关的增删查操作
  • 收获:复习了链表相关操作,1h。
/**
 * 2023/12/29 第三天 T3
 * 206.反转链表
 */
	//双指针写法
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode tmp = null;
        while (cur != null){ //注意循环条件cur != null
            tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }

    //递归写法 (待补充...)
  • 太久了忘记写法了。。

  • 思路:

    双指针法:注意使用到了 pre cur tmp 三个ListNode引用,其中cur用来遍历链表,pre用来保存前一个元素,tmp用来保存即将加入反转链表的旧链表的元素,为了防止旧链表断开后没有引用指向旧链表。

  • 收获:反转链表双指针解法,1h。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表是一种数据结构,用于存储一系列元素链表的主要特点是每个元素都包含指向下一个元素的指针,因此可以轻松地在链表中添加或删除元素,而不需要移动其他元素。下面是链表的具体使用方法: 1. 链表的定义:链表由节点组成,每个节点包含一个元素和一个指向下一个节点的指针。通常,链表有一个头节点,它不包含任何元素,但指向第一个节点。 2. 创建链表:创建链表时,需要先创建头节点,然后逐个创建每个节点并将它们连接起来。可以使用循环来完成这个过程。 3. 添加元素:要添加元素链表中,需要找到链表的尾部节点,然后创建一个新节点并将其链接到尾部节点。 4. 删除元素:要从链表中删除元素,需要找到要删除的节点并将其从链表移除。在链表中,删除节点时需要注意要修改前一个节点的指针,使其指向被删除节点的下一个节点。 5. 遍历链表:遍历链表可以使用循环,从头节点开始,逐个访问每个节点并处理它们的元素。 6. 查找元素:要查找链表中的元素,需要从头节点开始遍历链表,并比较每个节点的元素是否与目标元素相等。如果找到了目标元素,就返回它所在的节点,否则返回 null。 7. 反转链表反转链表可以使用三个指针,分别指向当前节点、前一个节点和后一个节点。在遍历链表时,将当前节点的指针指向前一个节点,然后将前一个节点、当前节点和后一个节点分别向后移动。 以上是链表的一些基本使用方法,具体使用时需要根据实际情况进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值