leetcode刷题(3)

简介: 各位朋友们大家好,今天是我leedcode刷题系列的第三篇,废话不多说,直接进入主题。

分割链表

leetcode之分割链表(难度:中等


题目要求

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。


你不需要 保留 每个分区中各节点的初始相对位置。


用例输入

示例 1:

image.png

输入:head = [1,4,3,2,5,2], x = 3

输出:[1,2,2,4,3,5]


示例 2:

输入:head = [2,1], x = 2

输出:[1,2]


这是题目提供的接口

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* partition(struct ListNode* head, int x){
}

提示

提示:

链表中节点的数目在范围 [0, 200] 内

-100 <= Node.val <= 100

-200 <= x <= 200


做题思路

我们可以使用一个指针来遍历链表,遇到比x值小的数字就放在左侧,大于或等于的结点就放在右侧,最后再用指针将这两个部分连接起来,得出来的就是我们需要的结果。

52.png

定义四个结构体指针:bs和be分别指向小于x部分链表的头和尾,as和ae分别指向大于或等于x部分链表的头和尾。

53.png

54.png

持续这个动作,知道cur等于NULL。

55.png

然后我们这两部分用指针连接起来。并且将ae手动置为NULL,防止链表出现死循环。

56.png

我们在做完了之后我们还需要注意的是:当只有小于x的值或者只有大于x的部分的时候我们上面的思路是不行的,我们需要做出判断,当bs为NULL时我们可以直接返回as,因为就算as也为NULL,返回的也是NULL。当as为NULL时,我们直接返回bs,不需要将ae置为NULL。


c语言代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* partition(struct ListNode* head, int x){
//定义四个结构体指针来管理小于和大于等于x两部分的链表
  //小于x部分的头节点
    struct ListNode* bs = NULL;
    //小于x部分的尾节点
    struct ListNode* be = NULL;
    //大于x部分的头节点
    struct ListNode* as = NULL;
    //大于x部分的尾节点
    struct ListNode* ae = NULL;
    //cur用来遍历链表
    struct ListNode* cur = head;
    while(cur != NULL)
    {
        if(cur->val < x)
        {
        //当第一次出现小于x的节点的时候,bs和be都是这个节点
            if(bs == NULL)
            {
                bs = cur;
                be = cur;
            }
            else
            {
                be->next = cur;
                be = be->next;
            }
        }
        else
        {
        //第一次出现大于x的节点
            if(as == NULL)
            {
                as = cur;
                ae = cur;
            }
            else
            {
                ae->next = cur;
                ae = ae->next;
            }
        }
        cur = cur->next;
    }
    //判断是否有小于x的节点
    if(bs == NULL)
    {
        return as;
    }
    //连接两部分链表
    be->next = as;
    //判断是否有大于x的节点
    if(as != NULL)
    {
        ae->next = NULL;
    }
    return bs;
}

57.png

Java代码实现

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode partition(ListNode head, int x) {
    //我们的Java代码与c语言略有不同,
    //我们将bs和as作为哨兵位
        if(head == null) {
            return null;
        }
        ListNode bs = new ListNode(0);
        ListNode be = bs;
        ListNode as = new ListNode(0);
        ListNode ae = as;
        ListNode cur = head;
        while(cur != null) {
            if(cur.val < x) {
                be.next = cur;
                be = be.next;
            }else {
                ae.next = cur;
                ae = ae.next;
            }
            cur = cur.next;
        }
        if(bs.next == null) {
            return as.next;
        }
        be.next = as.next;
        if(as.next != null) {
            ae.next = null;
        }
        return bs.next;
    }
}

58.png


相交链表

leetcode之相交链表(难度:简单)


题目要求

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。


图示两个链表在节点 c1 开始相交:

59.png

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。


用例输入

示例 1:

60.png

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3


输出:Intersected at ‘8’


解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。

从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。

在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

— 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。


示例 2:

image.png

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1


输出:Intersected at ‘2’


解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。

从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。

在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。


示例 3:

62.png

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2


输出:null


解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。

由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。

这两个链表不相交,因此返回 null 。


题目提供的接口

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
}

提示

提示:

listA 中节点数目为 m

listB 中节点数目为 n

1 <= m, n <= 3 * 104

1 <= Node.val <= 105

0 <= skipA <= m

0 <= skipB <= n

如果 listA 和 listB 没有交点,intersectVal 为 0

如果 listA 和 listB 有交点,intersectVal == listA[skipA] == listB[skipB]


做题思路

当这两个链表从后面剩余的节点的个数相同的地方开始走,他们会在相交节点相遇。但是因为两个链表的长度不一定是相同的,所以我们需要求出两个链表的长度的差值len,然后让长的链表先走len步,然后再一起走,当他们的地址相同时就说明到达了相交节点,我们就返回这个节点。


c语言实现代码

//我们将计算链表长度这个功能单独提出来,写成一个函数
int listLength(struct ListNode* head)
{
    struct ListNode* cur = head;
    int count = 0;
    while (cur != NULL)
    {
        count++;
        cur = cur->next;
    }
    return count;
}
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
//当其中一个链表为空就说明没有相交节点,我们直接返回
    if (headA == NULL || headB == NULL)
    {
        return NULL;
    }
    //我们将ll作为长度较长的链表的指针
    struct ListNode* ll = headA;
    //sl作为长度较短的链表的指针
    struct ListNode* sl = headB;
    int lenA = listLength(headA);
    int lenB = listLength(headB);
    int len = lenA - lenB;
    //如果len<0,我们就交换ll跟sl的指向
    if (len < 0)
    {
        ll = headB;
        sl = headA;
        len = -len;
    }
    for (int i = 0; i < len; i++)
    {
        ll = ll->next;
    }
    while (ll && sl)
    {
        if (ll == sl)
        {
            return ll;
        }
        ll = ll->next;
        sl = sl->next;
    }
    return NULL;
}

63.png

Java代码实现

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
 //链表长的就走差值步
 //pl永远指向较长的链表
 //p2永远指向较短的链表
public class Solution {
    public int getLength(ListNode head) {
        int count = 0;
        ListNode cur = head;
        while(head != null) {
            head = head.next;
            count++;
        }
        return count;
    }
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) {
            return null;
        }
        ListNode pl = headA;
        ListNode ps = headB;
        int len1 = getLength(pl);
        int len2 = getLength(ps);
        int len = len1-len2;
        if(len < 0) {
            pl = headB;
            ps = headA;
            len = -len;
        }
        while(len != 0) {
            pl = pl.next;
            len--;
        }
        while(pl != ps) {
            pl = pl.next;
            ps = ps.next;
        }
        return pl;
    }
}

64.png

相关文章
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
63 6
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
56 4
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
128 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
46 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
4月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
72 7
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
58 5
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
34 4
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
Leetcode题目"剑指 Offer 21. 调整数组顺序使奇数位于偶数前面"的两种Python解决方案,一种是使用双端队列调整数组顺序,另一种是使用双指针法将奇数移到数组前半部分,偶数移到后半部分。
29 4