该逻辑对于删除第一个元素不适用。

这样的代码不优美

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) { while(head!=NULL && head->val == val){
ListNode* delNode = head;
head = delNode ->next;
delete delNode;
} if(head == NULL)
return NULL; ListNode* cur = head; while(cur->next != NULL){
if(cur->next->val == val){
//删除
ListNode* delNode = cur->next;
cur->next = delNode->next;
delete delNode;
}
else
cur = cur->next;
} return head;
}
};

可以设置一个虚拟的头结点:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) { ListNode* dummyHead = new ListNode();
dummyHead->next = head; ListNode* cur = dummyHead; while(cur->next != NULL){
if(cur->next->val == val){
//删除
ListNode* delNode = cur->next;
cur->next = delNode->next;
delete delNode;
}
else
cur = cur->next;
} ListNode* retNode = dummyHead->next;
delete dummyHead;
return retNode;
}
};

这道题想了好久,原因是要把重复的所有元素都删除,这里设立一个duplicate标志位来记录当前cur是否与下一个结点重复。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* h = new ListNode(-);
h->next = head;
ListNode* pre = h;
ListNode* cur = head;
while(cur!=NULL){
bool duplicate = false;
while(cur->next!=NULL && cur->val==cur->next->val){
ListNode* delNode = cur;
cur = cur->next;
delete delNode;
duplicate = true;
}
if(duplicate == false){
pre = cur;
cur = cur->next;
}
else{
pre->next = cur->next;
ListNode* delNode = cur;
cur = cur->next;
delete delNode;
}
}
return h->next;
}
};

又重新做了一遍这道题,思路和前面设置标志位记录重复的不太一样。重点在于在两个结点不相同时,需要判断在它们前面是否存在重复的元素,若存在,pre需要跳过这些结点;若不存在,pre直接指向pre->next即cur即可。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(head == NULL)
return NULL;
ListNode dummy();
dummy.next = head;
ListNode* pre = &dummy, *cur = head;
while(cur){
ListNode* next = cur->next;
while(next && next->val == cur->val){
cur = cur->next;
next = next->next;
}
if(cur != pre->next){
cur = next; //将最后一个重复的跳过
pre->next = cur;
}
else{ //pre和cur之间没有重复的
pre = cur;
cur = next;
} }
return dummy.next;
}
};

归并两个有序的链表。

/**
* 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* h = new ListNode(-);
ListNode* cur = h;
ListNode* cur1 = l1;
ListNode* cur2 = l2;
while(cur1 != NULL && cur2 != NULL){
if(cur1->val <= cur2->val){
cur->next = cur1;
cur1 = cur1->next;
}
else{
cur->next = cur2;
cur2 = cur2->next;
}
cur = cur->next;
}
if(cur1 != NULL){
cur->next = cur1; }
if(cur2 != NULL){
cur->next = cur2; }
ListNode* ret = h->next;
delete h;
return ret;
}
};

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode();
dummyHead->next = head;
ListNode* p = dummyHead;
while(p->next && p->next->next){
ListNode* node1 = p->next;
ListNode* node2 = node1->next;
ListNode* next = node2->next; node2->next = node1;
node1->next = next;
p->next = node2; p = node1;
}
ListNode* ret = dummyHead->next;
delete dummyHead;
return ret;
}
};

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(!head || k==) return head;
ListNode* dummy = new ListNode(-);
ListNode* pre = dummy, *cur = head;
dummy->next = head;
int i = ;
while(cur){
i++;
if(i%k == ){
pre = reverseOneGroup(pre, cur->next);
cur = pre->next;
}
else{
cur = cur->next;
}
}
return dummy->next;
} ListNode* reverseOneGroup(ListNode* pre, ListNode* next){
ListNode* last = pre->next;
ListNode* cur = last->next;
while(cur!=next)
{
last->next = cur->next;
cur->next = pre->next; //注意这里是指向pre->next
pre->next = cur;
cur = last->next;
}
return last; //返回需要翻转的最后一个元素
}
};

用链表来实现插入排序。

思路:创建一个辅助的新链表,并且使用一个指针遍历原链表,每次将原链表中的一个节点插入到新链表的合适位置(即该节点的值大于新链表上的节点的值,又小于后一节点的值)。最后将新链表的头部返回即可。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) { if(head == NULL || head->next == NULL)
return head; ListNode* pre = new ListNode(-), *ans = pre; //创建一个新链表的头结点,并用一个临时变量来保存
ListNode* cur = head; //cur是原链表的指针
while(cur != NULL){
//每次循环前重置pre为头结点,保证每次都从头到尾遍历
pre = ans;
while(pre->next != NULL && pre->next->val < cur->val){
pre = pre->next;
} //此时,pre->next->val大于cur->val,应把cur插入到pre后
//保存原链表当前节点的下一个节点
ListNode* tmp = cur->next;
//插入cur到pre后
cur->next = pre->next;
pre->next = cur; cur = tmp; //cur在原链表中后移一位
}
return ans->next;
}
};

一样的思路,又写了一遍,创建一个新链表,dummy指向新链表的头结点。扫描原链表,对于每个结点v,从前往后扫描已排序好的结果链表,找到第一个比v大的u结点,将v插入到u之前。

时间复杂度:共遍历n个结点,为每个结点找到合适的位置,最多再遍历n次,所以总的时间复杂度是O(n^2)

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode *dummy = new ListNode(-); //dummy指向已排序链表的头结点 while(head){
ListNode* next = head->next;
ListNode *p = dummy;
while(p->next && p->next->val <= head->val)
p = p -> next; //p->next指向比head大的第一个结点,则p指向比head小的最后一个结点
//将head插入到p和p->next之间
head->next = p->next;
p->next = head; head = next;
}
return dummy->next;
}
};

本题适用于归并排序,难点是:怎么样找到分治时的middle指针,采用快慢指针的思想。快指针一次走两步,慢指针一次走一步,当快指针走到头时,慢指针刚好走到中间位置,此位置即为middle的位置。

快慢指针思想:

快慢指针是指指针移动的步长,快指针移动的快,慢指针移动的慢,例如可以让快指针一次移动两个步长,让慢指针一次移动一个步长。

快慢指针有两个比较重要的应用:

1、判断链表是否为单链表

2、在有序链表中寻找中位数

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
//将一个链表平分为两个链表
if(!head || !head->next) return head;
ListNode* slow = head, *fast = head, *pre = head;
while(fast && fast->next){
pre = slow;
slow = slow->next;
fast = fast->next->next;
}
pre->next = NULL;
return merge(sortList(head), sortList(slow));
} ListNode* merge(ListNode* l1, ListNode* l2){
ListNode* dummy = new ListNode(-);
ListNode* cur = dummy;
while(l1 && l2){
if(l1->val < l2->val){
cur->next = l1;
l1 = l1->next;
}
else{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
if(l1) cur->next = l1;
if(l2) cur->next = l2;
return dummy->next;
}
};

改变节点的值来解决问题。

/**
* 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) {
if(node == NULL)
return;
if(node->next == NULL){
delete node;
node = NULL;
return;
}
node->val = node->next->val;
ListNode* delNode = node->next;
node->next = delNode->next;
delete delNode;
return;
}
};

建立链表的虚拟头结点 203 Remove Linked List Element,82,147,148,237的更多相关文章

  1. leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点)

    203题是在链表中删除一个固定的值,83题是在链表中删除重复的数值,但要保留一个:82也是删除重复的数值,但重复的都删除,不保留. 比如[1.2.2.3],83题要求的结果是[1.2.3],82题要求 ...

  2. 单链表在不知头结点的情况下对第i个元素的删除

    一.首先,看看单链表中第i个元素的删除: Status ListDelete_L (LinkList &L,int i,ElemType &e){ //在带头结点的单链表L中,删除第i ...

  3. 203. Remove Linked List Elements - LeetCode

    Question 203. Remove Linked List Elements Solution 题目大意:从链表中删除给定的数 思路:遍历链表,如果该节点的值等于给的数就删除该节点,注意首节点 ...

  4. 203. Remove Linked List Elements【easy】

    203. Remove Linked List Elements[easy] Remove all elements from a linked list of integers that have ...

  5. LeetCode 203. Remove Linked List Elements 移除链表元素 C++/Java

    Remove all elements from a linked list of integers that have value val. Example: Input: ->->-& ...

  6. [刷题] 203 Remove Linked List Elements

    要求 在链表中删除值为val的所有节点 示例 如 1->2->3->4->5->6->NULL,要求删除值为6的节点 返回1->2->3->4-& ...

  7. 【LeetCode】203. Remove Linked List Elements

    Remove Linked List Elements Remove all elements from a linked list of integers that have value val. ...

  8. 【刷题-LeetCode】203. Remove Linked List Elements

    Remove Linked List Elements Remove all elements from a linked list of integers that have value *val* ...

  9. LeetCode 203. Remove Linked List Elements (移除链表中的项)

    Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --& ...

随机推荐

  1. 新浪SAE高级开发者认证通过

    如题,新浪SAE高级开发者认证通过,申请的方式为提交开源项目地址,用的是如下的项目 http://jqext.sinaapp.com/ 之前该项目是部署在 mopaas 上的,在拿到高级开发者资格后迁 ...

  2. c语言解二元二次方程组

    设a和b是正整数 a+b=30 且a*b=221 求a和b的值 思路就是穷举a和b的值,每次得到a和b的一个值,看是否同时满足a+b=30且a*b=221,如果满足,那么就输出. 那么a和b的的取值范 ...

  3. 实践作业3:接到任务及思考DAY1

    今天,老师又布置了新的学习任务,关于白盒测试.感觉黑盒测试,我们用的比较多,白盒测试就相对陌生了.上课的时候老师虽然也进行了一定的点拨,外加我们学习了SPOC视频,但是并没有看到什么具体的项目,所以实 ...

  4. 无限级分类及生成json数据

    第一步,先去数据库查询类别数据,然后交给生成json数据的函数处理,代码如下: /*生成类别JSON数据*/ public function wirteJson(){ $dataInfo = \thi ...

  5. MongoDB整理笔记のSharding分片

    这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群.MongoDB 的数据分块称为 chu ...

  6. XE改变图标颜色

    放一个image,load 一张png/..图片 再放一个FillRGBEffect, 将此控价拖到image下 改变FillRGBEffect的Color,就改变了image图标上的颜色. 原图为黑 ...

  7. vitamio遇到的坑,都是不能播放

    在模拟器上可以运行,在真机上不能用,一点就app全退了,不知原因,没办法用as连接到真机上调试,才发现是版本过高的原因,不支持sdk 23,大家的办法都是改成21, targetSdkVersion ...

  8. 关于 href="\\#" 和 return false

    href="\\#"  跳转到本页 return false 相当于不刷新 href="javascript:void(0)"   或者 href=" ...

  9. 类的互相包含------新标准c++程序设计

    #include<iostream> using namespace std; class A; class B{ public: void f(A* pt){}; } class A{ ...

  10. springboot项目部署运行(后台);端口被占用;

    打包: mvn clean package -Pprod -Dmaven.test.skip=true -Pprod 使用生产环境配置: -DskipTests,不执行测试用例,但编译测试用例类生成相 ...