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

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

今日学习的文章链接和视频链接

代码随想录

手把手带你学会操作链表

5098a8357c58434eac4f3febaced78c8.png自己看到题目的第一想法

(203.移除链表元素)有思路,但不会写,,,缺乏代码敏感性。


(707.设计链表)了解逻辑,但不会写,,,麻了。


( 206.反转链表 )感觉很简单,但节点交换和指针转换很绕,没绕出来。


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

(203.移除链表元素)常规思路:不加虚拟头节点。头节点是否=val,分等和不等两种情况。第二种方法:添加虚拟头节点。


(707.设计链表)声明初始化、增删改查。逻辑清晰


( 206.反转链表 )这么简洁,逻辑清晰。


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

(203.移除链表元素)代码块逻辑不清晰,双指针的作用及实现细节。


(707.设计链表)声明初始化不熟悉,到临界值不好确定,容易空想,画图解百忧。双向链表细节还有点迷。


( 206.反转链表 )应该定义几个节点?为什么?怎么保存节点?怎么调整指针?


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

(203.移除链表元素)代码块逻辑梳理,链表双指针各自意义及遍历细节。4h只是理解的阶段。自己实现估计又是一堆细节问题。

203.移除链表元素

// 不设置虚拟头节点的方式

// 两种情况:

// 头节点等于val值:更新头节点为下一节点。

// 头节点不等于val值:定义两个指针进行遍历,当前节点指针负责判别是否等于val值,前一节点指针根据当前节点是否等于val确定指向下一节点的位置。

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        // 头节点等于val值:
        while (head != null && head.val == val) {
            head = head.next;
        }
        // 为空
        if (head == null) {
            return head;
        }
        // 头节点不等于val值
        ListNode pre = head; // 记录当前节点前一指针,用于更新遍历
        ListNode cur = head.next;  // 记录当前节点,用于查找遍历
        while (cur != null) {
            if (cur.val == val) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return head;
    }
}

设置虚拟头节点的方式

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if (head == null) {
            return head;
        }
        //这行代码的作用是创建一个名为dummy的新的链表节点,并将原链表的头节点head作为dummy节点的下一个节点。
        //初始化值:新节点的值被设置为-1,这里的值可以是任意值,通常使用-1表示一个无效或占位的值。
        ListNode dummy = new ListNode(-1, head);
        ListNode pre = dummy;
        ListNode cur = head;
        while (cur != null) {
            if (cur.val == val) {
                pre.next = cur.next;
            } else {
                pre = cur;
            }
            cur = cur.next;
        }
        return dummy.next;
    }
}

707.设计链表

// 单链表
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);
    }
    // 获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
    public int get(int index) {
        //如果index非法,返回-1
        if (index < 0 || index >= size) {
            return -1;
        }
        ListNode currentNode = head;
        // 包含一个虚拟头节点,所以查找第index + 1 个节点
        for (int i = 0; i <= index; i++) { //
            currentNode = currentNode.next;
        }
        return currentNode.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++;
        ListNode pred = head;
        for (int i = 0; i < index; i++) {
            pred = pred.next;
        }
        ListNode toAdd = new ListNode(val);
        toAdd.next = pred.next;
        pred.next = toAdd;
    }
    public void deleteAtIndex(int index) {
        if (index < 0 || index >= size) {
            return;
        }
        size--;
        if (index == 0) {
            head = head.next;
            return;
        }
        ListNode pred = head;
        for (int i = 0; i < index; i++) {
            pred = pred.next; // 记录即将删除的下一节点,方便获取该节点的下一节点pred.next.next
        }
        pred.next = pred.next.next;
    }
}

206.反转链表

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode cur = head;
        ListNode temp = null;
        while (cur != null) {
            temp = cur.next; // 保存下一个节点
            cur.next = prev; // 改变指针方向
            prev = cur; // 前驱指针向后移动
            cur = temp; // 将cur改为下一节点
        }
        return prev; 
    }
}
相关文章
|
1月前
|
存储 算法 程序员
C 语言递归算法:以简洁代码驾驭复杂逻辑
C语言递归算法简介:通过简洁的代码实现复杂的逻辑处理,递归函数自我调用解决分层问题,高效而优雅。适用于树形结构遍历、数学计算等领域。
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
80 1
|
2月前
|
存储 缓存 算法
通过优化算法和代码结构来提升易语言程序的执行效率
通过优化算法和代码结构来提升易语言程序的执行效率
|
8月前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
7月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
7月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
7月前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
69 2
|
8月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
86 1
|
7月前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
7月前
|
存储 SQL 算法
LeetCode 83题:删除排序链表中的重复元素【面试】
LeetCode 83题:删除排序链表中的重复元素【面试】

热门文章

最新文章