2021-09-28每日刷题打卡

2021-09-28每日刷题打卡

力扣——链表

剑指 Offer II 027. 回文链表

给定一个链表的 头节点 head ,请判断其是否为回文链表。

如果一个链表是回文,那么链表节点序列从前往后看和从后往前看是相同的。

示例 1:

在这里插入图片描述

输入: head = [1,2,3,3,2,1]
输出: true

因为链表只能一节一节向前推进的原因,我们不能直接用对撞指针的方法来判断链表是否是回文链表,那么我们可以先遍历一遍链表,再把链表的值一个个存进vector里,再利用对撞指针判断。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
    if (head == NULL)
    {
        return true;
    }
    vector<int>v;
    int num;
    ListNode* p;
    p = (ListNode*)malloc(sizeof(ListNode));
    p->next = head;
    while (p->next != NULL)
    {
        p = p->next;
        num = p->val;
        v.push_back(num);
    }
    int left = 0, right = v.size() - 1;
    while (left < right)
    {
        if (v[left] != v[right])
        {
            return false;
        }
        left++;
        right--;
    }
    return true;
}
};
剑指 Offer 18. 删除链表的节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

注意:此题对比原题有改动

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

遍历链表,找到val值和目标val相同的结点,删除它。

删除结点的操作:让目标结点的上一个结点的next指向当前结点的next。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
    ListNode* p, * q;
    p = head;
    if (head == NULL)
    {
        return NULL;
    }
    if (head->val == val)
    {
        p = head->next;
        return p;
    }
    else
    {
        while (p->next != NULL)
        {
            if (p->next->val == val)
            {
                q = p->next;
                p->next = q->next;
            }
            p = p->next;
            if(p==NULL)
            {
                break;
            }
        }
    }
    return head;
}
};
剑指 Offer 06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2]
输出:[2,3,1]

把链表遍历一遍,把读到的val存入vector容器,再用reverse()把vector容器逆转。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int>v;
        while(head!=NULL)
        {
            v.push_back(head->val);
            head=head->next;
        }
        reverse(v.begin(), v.end());
        return v;
    }
};
141. 环形链表

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

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

如果链表中存在环,则返回 true 。 否则,返回 false 。

提示:

  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos-1 或者链表中的一个 有效索引

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

示例 1:

在这里插入图片描述

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

个人的想法是,如果出现环,则在遍历链表的时候必定会出现相同的值,如果没有环则不一定会出现相同的值,但题目没有告诉我们是否链表里的val会重复,如果本身就有重复的那这个方法就行不通了。但我们可以借用一下题目的规矩,题目告诉我们链表里的val范围是-10^5 <= Node.val <= 10^5,那我们就把遍历到的结点的val值改成一个不在此范围里的数,这样当我们遍历结点时遇到和我们设置相同的值就说明出现了环,不然该链表里不会出现超出这个范围的值。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        while(head!=NULL)
        {
            if(head->val!=-2000000)
            {
                head->val=-2000000;
            }else
            {
                return true;
            }
            head=head->next;
        }
        return false;
    }
};
160. 相交链表

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

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

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

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

在这里插入图片描述

示例 1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FI5Nz2Vv-1632826875321)(C:\Users\Aoxue\AppData\Roaming\Typora\typora-user-images\image-20210928190037473.png)]

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

一开始想法和上题一样,想着先遍历A,修改结点的val值;再遍历B,判断有没有出现过之前修改的val值,有的话就把那个结点返回,没有就返回NULL,但题目要求说不能修改链表的原始结构,而且val值不对也会判错,所以这个方法pass。那就只能用最蠢的方法了,遍历一遍A,把结点都存进vector容器里,vector容器要设置成<ListNode*>的类型。然后在遍历B的时候,每遍历一个结点就和vector容器里面的对比,如果相同就说明是相交的,返回那个结点,如果B遍历完了也没找到的话,说明不相交,返回NULL。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
    vector<ListNode*>v;
    while (headA != NULL)
    {
        v.push_back(headA);
        headA = headA->next;
    }
    while (headB != NULL)
    {
        for (int i = 0; i < v.size(); i++)
        {
            if (v[i] == headB)
            {
                return v[i];
            }
        }
        headB = headB->next;
    }
    return NULL;

}
};

(虽然这个方法过了但真的好慢啊orz)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值