首页 > 编程语言 >代码随想录算法训练营,8月30日 | 203.移除链表元素, 707.设计链表, 206.反转链表

代码随想录算法训练营,8月30日 | 203.移除链表元素, 707.设计链表, 206.反转链表

时间:2024-08-30 19:25:31浏览次数:14  
标签:ListNode cur val int 随想录 next 链表 移除

链表理论基础
1.单链表:数据域和指针域(指向下一个结点的位置)组成,头结点,结尾为空指针;双链表:多了一个指向前一个结点的指针;循环链表:结尾指向头结点。
2.链表在内存中的存储不是顺序的,跟数组不同,要找一个数据只能通过前一个数据来找,所有这就导致链表的查询比数组麻烦,但是插入删除数据却更方便(只用修改前面的数据的指针,以及将自己的指针指向下一个数据)。
3.Java里定义一个链表:

public class ListNode {
    int val;
    ListNode next;

    // 节点的构造函数(无参)
    public ListNode() {
    }
    // 节点的构造函数(有一个参数)
    public ListNode(int val) {
        this.val = val;
    }
    // 节点的构造函数(有两个参数)
    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

203.移除链表元素
题目链接:203.移除链表元素
文档讲解︰代码随想录(programmercarl.com)
视频讲解︰移除链表元素
日期:2024-08-30

思路:1.移除链表的元素想到链表的结构,将要移除的元素的前一个元素的指针变成指向它的下一个元素的就行了,但还要考虑到头结点没有前一个元素,单独提出来操作;
2.增加一个虚拟头结点指向头结点就可以免去单独操作头结点的操作。
Java代码如下:

//原数组上操作
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        while(head != null && head.val == val){
            head = head.next;
        }
        ListNode cur = head;
        while(cur != null && cur.next != null){
            if(cur.next.val == val){
                cur.next = cur.next.next;
            }else{
                cur = cur.next;
            }
        }
        return head;
    }
}
//虚拟头结点
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummyHead = new ListNode();
        dummyHead.next = head;
        ListNode cur = dummyHead;
        while(cur != null && cur.next != null){
            if(cur.next.val == val){
                cur.next = cur.next.next;
            }else{
                cur = cur.next;
            }
        }
        return dummyHead.next;//注意这个才是新的头结点
    }
}

总结:链表很多时候都要考虑特殊的那个头结点,加一个虚拟的头结点就让它不特殊了,可以像其他结点一样操作

707.设计链表
题目链接:707.设计链表
文档讲解︰代码随想录(programmercarl.com)
视频讲解︰设计链表
日期:2024-08-30

思路:首先这道题要先知道Java中链表的结构是怎么定义的,清楚了后再考虑是不是能用虚拟头结点来避免很多有关头结点的讨论,还有一点就是既然有要求再index这个位置插入,那么我必须知道index这个值到底在不在链表中,所有我们在定义MyLinkedList时还要考虑一个size这个值,并且后面增删也要对应的改动。
Java代码如下:

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 MyLinkedList {
    int size;
    ListNode dummyHead;
    public MyLinkedList() {
        dummyHead = new ListNode(0);//这是一个虚拟头结点
        size = 0;
    }
    
    public int get(int index) {
        if(index < 0 || index > size - 1){
            return -1;
        }
        ListNode cur = dummyHead;
        for(int i = 0; i < index + 1; i++){//这里的是index + 1
            cur = cur.next;
        }
        return cur.val;
    }
    
    public void addAtHead(int val) {
        ListNode node = new ListNode(val);
        node.next = dummyHead.next;
        dummyHead.next = node;
        size++;
    }
    
    public void addAtTail(int val) {
        ListNode node = new ListNode(val);
        ListNode cur = dummyHead;
        while(cur.next != null){
            cur = cur.next;
        }
        cur.next = node;
        size++;
    }
    
    public void addAtIndex(int index, int val) {
        if(index < 0 ){
            index = 0;
        }
        if(index > size){
            return;
        }
        ListNode node = new ListNode(val);
        ListNode cur = dummyHead;
        for(int i = 0; i < index; i++){
            cur = cur.next;
        }
        node.next = cur.next;
        cur.next = node;
        size++;
    }
    
    public void deleteAtIndex(int index) {
        if(index < 0 || index > size - 1){
            return;
        }
        ListNode cur = dummyHead;
        for(int i = 0; i < index; i++){
            cur = cur.next;
        }
        cur.next = cur.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);
 */

总结:清楚了链表的定义以及用了虚拟头结点后就比较容易了,增删也是些基本的操作。

206.反转链表
题目链接:206.反转链表
文档讲解︰代码随想录(programmercarl.com)
视频讲解︰反转链表
日期:2024-08-30

思路:直接在链表原本上操作,改下指针的方向,从头开始的话cur = head,cur要指向null(pre前一个结点),但这之前要保留下cur.next,反转完了,pre变为cur,cur变为之前保留的那个后续的结点,直到cur.next为null。
Java代码如下:

/**
 * 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 cur = head;
        ListNode pre = null;
        ListNode temp = null;
        while(cur != null){
            temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

总结:实际上手时while判定出错了,while里面已经将cur设置为了后一位,所有判定条件直接是cur != null就行,而不是cur.next;最后返回的值pre才是头的位置,第一次想当然以为是cur。

标签:ListNode,cur,val,int,随想录,next,链表,移除
From: https://www.cnblogs.com/wowoioo/p/18389378

相关文章

  • 「代码随想录算法训练营」第四十九天 | 图论 part7
    目录最小生成树的解题prim算法举例说明(来自代码随想录)题目:53.寻宝Kruskal算法举例说明(来自代码随想录)题目:53.寻宝最小生成树的解题最小生成树类型的题目主要用于解决所有节点的最小连通子图的问题,即:以最小的成本(边的权值)将图中所有节点链接到一起。最小生成树可以使用prim算......
  • 顺序表和链表知识点
    1顺序表顺序表是指用一段物理地址连续的空间去存储数据的线性结构。顺序表有两种:静态顺序表,动态顺序表。1.1静态顺序表结构体定义typedefintElemDataSL;typedefstructSequeList{ ElemDataSLarr[100]; intsize;}SL;静态顺序表在创建结构体的时候就已经把......
  • 分享丨【题单】链表、二叉树与一般树(前后指针/快慢指针/DFS/BFS/直径/LCA)
    作者:灵茶山艾府链接:https://leetcode.cn/circle/discuss/K0n2gO/一、链表注:由于周赛中的链表题可以转成数组处理,难度比直接处理链表低,故不标明难度分。带着问题去做下面的题目:在什么情况下,要用到哨兵节点(dummynode)?在什么情况下,循环条件要写while(node!=null)?什么情况......
  • 代码随想录day45 || 115 不同子序列, 583 两个字符串删除操作, 72 编辑距离
    115不同子序列funcnumDistinct(sstring,tstring)int{ //动态规划,思考一下判断连续和不连续的区别,如果相等都是左上角+1,如果不等,连续情况就是直接等于左上角,不连续情况直接归零 //dp[i][j]表示s[i]中存在t[j]结尾的的个数 //递推公式,不要求连续字串,所以,如果s[i......
  • 代码随想录算法day3 - 链表1
    题目1203.移除链表元素给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。示例1:输入:head=[1,2,6,3,4,5,6],val=6输出:[1,2,3,4,5]示例2:输入:head=[],val=1输出:[]示例3:输入:head=[7,7,7,7],v......
  • 数据结构-单链表-详解-1
    数据结构-单链表-详解-11.前言2.结点3.打印3.1关于断言3.2下一结点的找法物理结构逻辑结构1.前言在数据结构-顺序表-详解中,我详细介绍了顺序表的实现,而顺序表也有一些缺点:中间,头部插入时,需整体挪动数据,效率低下。空间不够时扩容,有一定的消耗,也可能有一定空间浪费......
  • 数据结构:双向链表
    目录结构体创建链表插入链表头插法尾插法 遍历打印删除更新查找销毁结构体typedefintDataType;typedefstructnode{structnode*pPre;DataTypedata;structnode*pNext;}LinkNode;创建链表LinkNode*CreateDouList(){LinkNode......
  • 代码随想录算法训练营,29日 | 704. 二分查找,27. 移除元素,977.有序数组的平方,209.长度最
    数组基础文档讲解︰代码随想录(programmercarl.com)1.连续空间、相同类型元素2.元素只能覆盖3.二维数组的地址连续吗(C++连续,Java不连续)704.二分查找题目链接:704.二分查找文档讲解︰代码随想录(programmercarl.com)视频讲解︰二分查找日期:2024-08-29思路:第一反应是想到二分查......
  • 力扣: 环形链表
    文章目录需求MapSet快慢指针结尾需求给你一个链表的头节点head,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从0开始)。......
  • 代码随想录算法day2-数组2
    题目1209.长度最小的子数组给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的子数组[numsl,numsl+1,...,numsr-1,numsr],并返回其长度。如果不存在符合条件的子数组,返回0。示例1:输入:target=7,nums=[2,......