题目一:在O(1)时间删除链表结点
给定单向链表的一个节点指针,定义一个函数在O(1)时间删除该结点。
假设链表一定存在,并且该节点一定不是尾节点。
JAVA
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
ListNode p = node.next;
node.val = p.val;
node.next = p.next;
p=null;
}
}
C++
/**
* 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) {
auto p =node->next;
// node->val = p->val;
// node->next = p->next;
*node = *(node->next);
delete p;
}
};
二.删除链表中重复的节点
一个指针 p指向原来的 pHead
一个指针 pre 指向新的 newHead
class Solution {
public:
ListNode* deleteDuplication(ListNode* head) {
ListNode* newHead = new ListNode(-1);
newHead->next = head;
ListNode* pre = newHead;
ListNode* p = head;
ListNode* q =NULL;
while(p && p->next){ //这里还要p 不为空
q=p->next;
if(p->val==q->val){
while(q&&q->val==p->val)
q=q->next;
pre->next =q;
p=q;
}
else{
pre=p;
p=q;
}
}
return newHead->next;
}
};
只要一个指向 newHead 的指针:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* head) {
auto newHead = new ListNode(-1);
newHead->next =head;
ListNode* p = newHead;
ListNode* q =NULL;
while(p->next){
q= p->next;
while(q && q->val==p->next->val)
q=q->next; //q跳出这个while的时候 q的值和p的值已经不等了
//因为p指向的是newHead q才是链表的第一个数,也就算说
//p之后的两个数不重复
if(p->next->next==q)
p=p->next;//q之前的一个数判断了 但是q在下一个数的第一个位置
else //p和q差了一个以上 说明 p之后到q之前的数是重复的 直接跳过
p->next=q;
}
return newHead->next;
}
};
在二的基础上改:重复出现的数也要保留下一个:
就是只有一个指针的判断
while(q&&q->val== p->val)
q=q->next;
if(p->next!=q) // 只有一开始走了while循环才会有p->next !=q 这时候
p->next=q;
else
p=q;
C++:
class Solution {
public:
ListNode* deleteDuplication(ListNode* pHead)
{
ListNode* newHead = new ListNode(-1);
newHead->next =pHead;
ListNode* p = newHead;
while(p->next){
ListNode* q= p->next;
//因为 p指向的是newHead 这个while第一个数是不去判断的
//因为我们要是的是重复也要保留下一个,所以直接 p=q了
//第二层循环开始 才会判断while,如果等了
//q是到了第一个和p不等的数
while(q&&q->val== p->val)
q=q->next;
//如果 q跳了很多次 说明p重复了 我们的p已经有一个了
//直接就p-next=q 指向q的第一个数就行了
if(p->next!=q)
p->next=q;
//如果q在p的后面 那就说明只有一个p的值 直接p=q
else
p=q;
}
return newHead->next;
}
};