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:
输入: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)