删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。
现有一个链表 – head = [4,5,1,9],它可以表示为:
示例 1:
输入: head = [4,5,1,9], node = 5 输出: [4,1,9] 解释: 给定你链表中值为 5
的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9. 示例 2:输入: head = [4,5,1,9], node = 1 输出: [4,5,9] 解释: 给定你链表中值为 1
的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
。。。。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
ListNode* temp = node->next;
int value = temp->val;
if(temp->next!=NULL){
node -> next = temp -> next;
node -> val = value;
}else{
node -> next = NULL;
node -> val = value;
}
}
};
删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
快慢指针,找到节点后和第一题一样
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* fast = head,*slow = head;
if(head->next == NULL)
return NULL;
if(head->next->next == NULL){
if(n==1){
head->next = NULL;
return head;
}
if(n==2){
head = head -> next;
return head;
}
}
while(n > 0){
fast = fast -> next;
n--;
if(fast -> next == NULL && n>0){
head = head -> next;
return head;
}
}
while(fast->next!=NULL){
fast = fast -> next;
slow = slow -> next;
}
slow->next = slow->next->next;
return head;
}
};
反转链表
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
利用3根指针诸位反转
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL||head->next==NULL)
return head;
if(head->next->next==NULL){
ListNode* temp = head;
head = head->next;
head->next = temp;
temp->next = NULL;
return head;
}
ListNode* mid = head->next;
ListNode* left = head;
ListNode* right = head->next->next;
left->next = NULL;
while(right->next!=NULL){
mid->next = left;
left = mid;
mid = right;
right = right->next;
}
mid->next = left;
right->next = mid;
return right;
}
};
合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4
有点归并排序那意思了
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* res=NULL;
if(l1==NULL&&l2==NULL)
return res;
if(l1==NULL)
return l2;
if(l2==NULL)
return l1;
if(l1->val >= l2->val){
res = l2;
l2 = l2->next;
}else{
res = l1;
l1 = l1->next;
}
ListNode* temp=res;
while(l1!=NULL||l2!=NULL){
if(l1==NULL){
temp->next = l2;
temp = temp->next;
l2 = l2->next;
continue;
}
if(l2==NULL){
temp->next = l1;
temp = temp->next;
l1 = l1->next;
continue;
}
if(l1->val >= l2->val){
temp->next = l2;
temp = temp->next;
l2 = l2->next;
}else{
temp->next = l1;
temp = temp->next;
l1 = l1->next;
}
}
return res;
}
};
回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2 输出: false 示例 2:
输入: 1->2->2->1 输出: true 进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
利用栈和快慢指针实现,如果要做到O(1)的空间复杂度,需要翻转后半部分的链表,改变原数据。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(!head||head->next==NULL)
return true;
ListNode* fast = head,*slow = head;
while(fast!=NULL){
slow = slow->next;
if(fast->next == NULL||fast->next->next == NULL)
break;
fast = fast->next->next;
}
stack<int> help;
while(slow!=NULL){
help.push(slow->val);
slow = slow->next;
}
while(!help.empty()){
if(help.top()!=head->val)
return false;
head = head->next;
help.pop();
}
return true;
}
};
环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是
-1,则在该链表中没有环。示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1 输出:false 解释:链表中没有环。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
经典问题,快慢指针
/**
* 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) {
if(!head)
return false;
ListNode *fast=head,*slow=head;
do{
if(fast->next==NULL||fast->next->next==NULL)
return false;
fast = fast->next->next;
slow = slow->next;
}while(fast!=slow);
return true;
}
};