首页 > 其他分享 >单向链表 - OJ

单向链表 - OJ

时间:2024-08-10 23:25:18浏览次数:9  
标签:head ListNode OJ 单向 fast next 链表 null

题目一:

删除链表中等于给定值 val 的所有节点。 

203. 移除链表元素 - 力扣(LeetCode)

【思路】:可以先想想只删除一个val怎么删的。

public ListNode removeElements(ListNode head, int val) {
        //链表为空
        if (head == null) {
            return head;
        }

        //1.删除第一个节点之后所有的val
        ListNode pre = head;
        ListNode find = null;
        while (pre.next != null) {
            find = pre.next;
            if (find.val == val) {
                //pre本身不变,pre的next更改指向
                pre.next = find.next;
            } else {
                //pre本省更改指向
                pre = find;
            }
        }

        //2.删除第一个节点中的val
        if (head.val == val) {
            head = head.next;
        }
        return head;
}

题目二:

反转一个单链表。

206. 反转链表 - 力扣(LeetCode)

public ListNode reverseList(ListNode head) {
        //判断链表是否为空
        if (head == null) {
            return head;
        }

        ListNode cur = head.next;//待前移元素

        //1. 将头节点的next置为null
        head.next = null;

        //2.开始翻转
        while (cur != null) {
            ListNode curN = cur.next;//写在循环里面的原因是,如果cur == null,则curN会出现空指针异常
            cur.next = head;
            head = cur;
            cur = curN;
        }
        return head;
}

题目三:

给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

876. 链表的中间结点 - 力扣(LeetCode)

【思路】:相同时间下,路程与速度成正比。

public ListNode middleNode(ListNode head) {
        //依题意得,链表不可能为空,所以不用额外判断链表为空的情况

        ListNode fast = head;
        ListNode slow = head;

        //根据画图可得循环的条件要写成什么
        while (fast != null && fast.next != null) {//注意一下条件的书写顺序,否则会出现空指针异常
            fast = fast.next.next;//走两步
            slow = slow.next;//走一步
        }
        return slow;
}

题目四:

输入一个链表,输出该链表中倒数第k个结点。

面试题 02.02. 返回倒数第 k 个节点 - 力扣(LeetCode)

【添加条件】:判断k是否越界,且整道题只能一次遍历链表。

public int kthToLast(ListNode head, int k) {
        //判断链表是否为空, 判断k是否合法
        if (head == null || k <= 0) {
            return -1;
        }

        //开始遍历
        ListNode fast = head;
        ListNode slow = head;

        //让fast先走k-1步
        for (int i = 0; i < k - 1; i++) {
            fast = fast.next;
            //判断k是否合法
            if (fast == null) {
                return -1;
            }
        }

        //让fast和slow一起走
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow.val;
}

题目五:

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

21. 合并两个有序链表 - 力扣(LeetCode)

【提示】:new一个新的傀儡节点

public ListNode mergeTwoLists(ListNode headA, ListNode headB) {
        //定义傀儡节点(有new)
        //如果不new,则要在while循环中额外判断newHead是否为nll
        ListNode newHead = new ListNode();
        ListNode cur = newHead;
        
        //正常(已考虑到了haedA、headB为空的情况)
        while (headA != null && headB != null) {
            if (headA.val < headB.val) {
                cur.next = headA;
                headA = headA.next;
            } else {
                cur.next = headB;
                headB = headB.next;
            }
            cur = cur.next;
        }

        if (headA == null) {
            cur.next = headB;
        }

        if (headB == null) {
            cur.next = headA;
        }
        return newHead.next;
}

题目六:

以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前。

链表分割_牛客题霸_牛客网 (nowcoder.com)

public ListNode partition(ListNode head, int x) {
        // write code here
        ListNode curA = new ListNode(-1);
        ListNode curAN = curA;
        ListNode curB = new ListNode(-1);
        ListNode curBN = curB;

        while (head != null) {
            if (head.val < x) {
                curAN.next = head;
                curAN = curAN.next;
            } else {
                curBN.next = head;
                curBN = curBN.next;
            }
            head = head.next;
        }

        if (curA.next == null) {
            return curB.next;
        }
        curAN.next = curB.next;
        if (curB.next == null) {
            return curA.next;
        }
        curBN.next = null;
        return curA.next;
}

题目七:

链表的回文结构。

链表的回文结构_牛客题霸_牛客网 (nowcoder.com)

public boolean chkPalindrome(ListNode head) {
        // write code here
        //如果不额外判断后面的代码会报空指针异常
        if (head == null) {
            return true;
        }

        //1. 找到中间节点
        ListNode fast = head;
        ListNode slow = head;

        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        //2. 翻转中间节点之后的节点
        ListNode cur = slow.next;

        while (cur != null) {
            ListNode curN = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curN;
        }
        //while循环走完之后slow所指向的节点就是右边最后一个节点

        //3.比较对应位置的前后节点
        while (head != slow) {//如果节点是偶数,这两个节点永远不会相遇
            if (head.val != slow.val) {
                return false;
            } else {
                if (head.next == slow) {
                    return true;
                }
                head = head.next;
                slow = slow.next;
            }
        }
        return true;
}

题目八:

输入两个链表,找出它们的第一个公共结点。

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //假设链表A长于链表B

        //1. 计算链表A、B的长度
        ListNode curA = headA;
        ListNode curB = headB;
        int countA = 0;
        int countB = 0;

        while (curA != null) {
            countA++;
            curA = curA.next;
        }

        while (curB != null) {
            countB++;
            curB = curB.next;
        }

        //2. 判断到底哪一个链表长
        int len = countA - countB;
        if (len < 0) {//如果是则,链表B长
            curA = headB;
            curB = headA;
            len = countB - countA;
        } else {
            //3. 让curA、B的值回归
            curA = headA;
            curB = headB;
        }

        //4. 让长链表先走len步
        for (int i = 0; i < len; i++) {
            curA = curA.next;
        } 

        //5. 找节点
        while (curA != curB) {//此时如果到了最后(null)也会跳出
            curA = curA .next;
            curB = curB.next;
        }

        //6. 判断是否由于为null而跳出的
        if (curA == null) {
            return null;
        }
        return curA;
}

题目九:

给定一个链表,判断链表中是否有环。

【提示】:如果有环则fast和slow一定会相遇,但相遇的点不知道是环里的那点。

public boolean hasCycle(ListNode head) {
        //1. 定义快慢指针
        ListNode fast = head;//每次走两步
        ListNode slow = head;//每次走一步

        //2. 判断fast是否能==slow,head==null的情况已包含其中
        //这个条件要自己举例试出来
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                return true;
            }
        }
        return false;
}

题目十: 

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL。

142. 环形链表 II - 力扣(LeetCode)

public ListNode detectCycle(ListNode head) {
        //1. 定义快慢指针
        ListNode fast = head;//每次走两步
        ListNode slow = head;//每次走一步

        //2. 判断fast是否能==slow,head==null的情况已包含其中
        //这个条件要自己举例试出来
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) {
                break;
            }
        }

        //如果发现没有环则这届返回null
        if (fast == null || fast.next == null) {
            return null;
        }

        //如果在环中相遇,则fast、slow此时就是相遇节点
        fast = head;

        //3. 找入口节点
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
}

标签:head,ListNode,OJ,单向,fast,next,链表,null
From: https://blog.csdn.net/YX54201/article/details/141016757

相关文章

  • UOJ #712. 【北大集训2021】简单数据结构
    Description你有一个长度为\(n\)的序列\(a\),下面你要进行\(q\)次修改或询问。给定\(v\),将所有\(a_i\)变为\(\min(a_i,v)\)。将所有\(a_i\)变为\(a_i+i\)。给定\(l,r\),询问\(\sum_{i=l}^ra_i\)。\(1\leqn,q\leq2\times10^5,0\leqa_i,v_i\leq10^{12}......
  • 数据结构之线性表(单链表的实现)
    目录一、单链表的原理二、单链表的实现1.单链表的定义2.单链表的初始化3.清空单链表4.单链表是否为空5.单链表的长度6.获取指定位置i的元素7.获取指定元素e的位置  8.向链表中插入指定位置的元素9.向链表中删除指定位置的元素10.遍历链表中的元素三、打印测......
  • 线性表——双链表
    在Java中,双链表(DoublyLinkedList)是一种常见的数据结构,它允许从两端进行元素的插入和删除操作。与单链表相比,双链表的每个节点除了存储数据本身外,还包含两个指针:一个指向前一个节点(prev),另一个指向后一个节点(next)。这使得双链表在遍历、插入和删除操作上更加灵活。双链表提供......
  • Leetcode 206. 反转链表
    给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。示例1:输入:head=[1,2,3,4,5]输出:[5,4,3,2,1]示例2:输入:head=[1,2]输出:[2,1]示例3:输入:head=[]输出:[]提示: 链表中节点的数目范围是 [0,5000]-5000<=Node.val<=5000方法一: //双指......
  • [开题报告]FLASK框架图书馆座位预约系统oj14m(源码+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高校教育规模的不断扩大,图书馆作为知识资源与学习空间的核心,其座位资源的有效管理日益成为关注焦点。传统的先到先得模式不仅容易导致......
  • 二叉树基础OJ题
    前言二叉树学到现在,我们对递归已经一定程序上的理解了,所有这里为了加深我们对二叉树递归的掌握,我会分享几道基础的练习题来巩固加深我们对二叉树的理解这里拿出一些二叉树OJ题,我会写出过程详解,如有错误还望指正!题源来自于牛客网和力扣单值二叉树这题需要判断每个节点的值......
  • UOJ354 新年的投票
    最近我博客似乎出了点bug,倒是不太会修,将就着看吧。本文主要关注第四个子任务,前面三个有叙述不清的敬请谅解。UOJ354新年的投票Sub1不管人的编号直接爆搜就能够找到一个合法方案。Sub3第\(i\)个人假设自己是第一个\(1\),\(1\simi-1\)的都不能是\(1\),如果自己确实有这......
  • Mojo 中的光线追踪
    本教程基于热门教程《C++中的可理解光线追踪》。该教程很好地描述了数学解释,因此在Mojo中实现基本光线追踪器时,我们只会向您指出相应的部分以供参考。步骤1:基本定义我们首先定义一个Vec3f结构体,用于表示3D空间中的矢量以及RGB像素。我们将使用SIMD矢量的表示形式......
  • 单链表的增删查改
    头文件#define_CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<assert.h>typedefstructMyStruct{   intdata;   structMyStruct*next;}SL;voidlistprint(SL**phead);//打印链表voidlistpushback(SL**phead,intx);/......
  • [lnsyoj2246/luoguCF979D]Kuro and GCD and XOR and SUM
    题意给定集合\(S\),初始为空,进行\(q\)次修改或查询操作:修改操作将\(x\)加入集合;查询操作给定\(x,s,k\),要求找到满足\[\max_{u\inS,u+x\les,k|\gcd(u,x)}\{u\oplusx\}\]的最小的\(u\)。sol集合、异或、可查可改,可以自然地想到0/1-Trie。我们假设\(k=1\),此时不需......