Leetcode常见链表问题及代码示例

网友投稿 230 2022-11-11


Leetcode常见链表问题及代码示例

按规定区间反转链表

思路:可以考虑成一种把前后数字的结点断开重新组合的问题

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* reverseBetween(ListNode* head, int m, int n) {

ListNode *dummy = new ListNode(-1), *pre = dummy;

dummy->next = head;

for (int i = 0; i < m - 1; ++i)

pre = pre->next;

ListNode *cur = pre->next;

for (int i = m; i < nhttp://; ++i) {

ListNode *t = cur->next;

cur->next = t->next;

t->next = pre->next;

pre->next = t;

}

return dummy->next;

}

};

分割链表

思路:先找到一个大于或者等于给定值的节点,然后再逐个把小于他们的值放在前面。例如本例先找到4,然后再找到3,然后把小于3的值都放在其前面

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* partition(ListNode* head, int x) {

ListNode *p=new ListNode(-1);

p->next=head;

ListNode *pre=p,*cur=head;

while(pre->next&&pre->next->val

pre=pre->next;

cur=pre;

while(cur->next){

if(cur->next->val

ListNode *tmp=cur->next;

cur->next=tmp->next;

tmp->next=pre->next;

pre->next=vBAvOPQXpAtmp;

pre=pre->next;

}else{

cur=cur->next;

}

}

return p->next;

}

};

逆序链表存储数相加

思路:先建立一个p结点,然后将相加生成的新结点按顺序放到p结点之后,然后再用一个新指针cur指向新链表的最后一位。设置一个进位计数res,当两个结点值相加之后,可以用sum/10来表示进位,然后以sum%10来建立新的结点。最后需要注意的是最高位的进位问题,所以while结束后要,如果res为1,则再建一个值为1的结点。

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

ListNode *p=new ListNode(-1),*cur=p;

int res=0;

while(l1||l2){

int val1=l1?l1->val:0;

int val2=l2?l2->val:0;

int sum=val1+val2+res;

res=sum/10;

cur->next=new ListNode(sum%10);

cur=cur->next;

if(l1)

l1=l1->next;

if(l2)

l2=l2->next;

}

if(res)

cur->next=new ListNode(1);

return p->next;

}

};

顺序链表存储相加

思路:这道题和第2题类似,但是链表是从前往后遍历,加法却要从最低位相加,所以可以考虑改用栈来存储放进来的数据。

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

stack s1, s2;

while (l1) {

s1.push(l1->val);

l1 = l1->next;

}

while (l2) {

s2.push(l2->val);

l2 = l2->next;

}

int sum = 0;

ListNode *res = new ListNode(0);

while (!s1.empty() || !s2.empty()) {

if (!s1.empty()) {

sum += s1.top();

s1.pop();

}

if (!s2.empty()) {

sum += s2.top();

s2.pop();

}

res->val = sum % 10;

ListNode *cur = new ListNode(sum / 10);

cur->next = res;

res = cur;

sum /= 10;

}

return res->val == 0 ? res->next : res;

}

};

移除链表元素

思路:直接递归调用到链表末尾,然后回来,需要删除的元素将链表next指针指向下一个元素即好。

/**

* 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) {

if(!head) return NULL;

head->next=removeElements(head->next,val);

return head->val==val?head->next:head;

}

};

删除排序链表中的重复元素

思路:递归查找,如果head的值存在且相等,那么while循环跳过后面所有值相等的结点,如果后面if还有值相等则继续进行递归。如果最后到head的值不同后,返回到head即可。<这种方式比新建链表存储时间负责度高很多>

/**

* 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) return head;

if (head->next && head->val == head->next->val) {

while (head->next && head->val == head->next->val) {

head = head->next;

}

return deleteDuplicates(head->next);

}

head->next = deleteDuplicates(head->next);

return head;

}

};

删除顺序链表中的重复元素

思路:head结点的值和身后结点的值进行比较,如果值相同,则返回后面一个结点。最后回溯递归调用删除重复结点。

/**

* 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||!head->next) return head;

head->next=deleteDuplicates(head->next);

return (head->val==head->next->val)?head->next:head;

}

};

pre=pre->next;

cur=pre;

while(cur->next){

if(cur->next->val

ListNode *tmp=cur->next;

cur->next=tmp->next;

tmp->next=pre->next;

pre->next=vBAvOPQXpAtmp;

pre=pre->next;

}else{

cur=cur->next;

}

}

return p->next;

}

};

逆序链表存储数相加

思路:先建立一个p结点,然后将相加生成的新结点按顺序放到p结点之后,然后再用一个新指针cur指向新链表的最后一位。设置一个进位计数res,当两个结点值相加之后,可以用sum/10来表示进位,然后以sum%10来建立新的结点。最后需要注意的是最高位的进位问题,所以while结束后要,如果res为1,则再建一个值为1的结点。

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

ListNode *p=new ListNode(-1),*cur=p;

int res=0;

while(l1||l2){

int val1=l1?l1->val:0;

int val2=l2?l2->val:0;

int sum=val1+val2+res;

res=sum/10;

cur->next=new ListNode(sum%10);

cur=cur->next;

if(l1)

l1=l1->next;

if(l2)

l2=l2->next;

}

if(res)

cur->next=new ListNode(1);

return p->next;

}

};

顺序链表存储相加

思路:这道题和第2题类似,但是链表是从前往后遍历,加法却要从最低位相加,所以可以考虑改用栈来存储放进来的数据。

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

stack s1, s2;

while (l1) {

s1.push(l1->val);

l1 = l1->next;

}

while (l2) {

s2.push(l2->val);

l2 = l2->next;

}

int sum = 0;

ListNode *res = new ListNode(0);

while (!s1.empty() || !s2.empty()) {

if (!s1.empty()) {

sum += s1.top();

s1.pop();

}

if (!s2.empty()) {

sum += s2.top();

s2.pop();

}

res->val = sum % 10;

ListNode *cur = new ListNode(sum / 10);

cur->next = res;

res = cur;

sum /= 10;

}

return res->val == 0 ? res->next : res;

}

};

移除链表元素

思路:直接递归调用到链表末尾,然后回来,需要删除的元素将链表next指针指向下一个元素即好。

/**

* 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) {

if(!head) return NULL;

head->next=removeElements(head->next,val);

return head->val==val?head->next:head;

}

};

删除排序链表中的重复元素

思路:递归查找,如果head的值存在且相等,那么while循环跳过后面所有值相等的结点,如果后面if还有值相等则继续进行递归。如果最后到head的值不同后,返回到head即可。<这种方式比新建链表存储时间负责度高很多>

/**

* 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) return head;

if (head->next && head->val == head->next->val) {

while (head->next && head->val == head->next->val) {

head = head->next;

}

return deleteDuplicates(head->next);

}

head->next = deleteDuplicates(head->next);

return head;

}

};

删除顺序链表中的重复元素

思路:head结点的值和身后结点的值进行比较,如果值相同,则返回后面一个结点。最后回溯递归调用删除重复结点。

/**

* 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||!head->next) return head;

head->next=deleteDuplicates(head->next);

return (head->val==head->next->val)?head->next:head;

}

};

ListNode *tmp=cur->next;

cur->next=tmp->next;

tmp->next=pre->next;

pre->next=vBAvOPQXpAtmp;

pre=pre->next;

}else{

cur=cur->next;

}

}

return p->next;

}

};

逆序链表存储数相加

思路:先建立一个p结点,然后将相加生成的新结点按顺序放到p结点之后,然后再用一个新指针cur指向新链表的最后一位。设置一个进位计数res,当两个结点值相加之后,可以用sum/10来表示进位,然后以sum%10来建立新的结点。最后需要注意的是最高位的进位问题,所以while结束后要,如果res为1,则再建一个值为1的结点。

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

ListNode *p=new ListNode(-1),*cur=p;

int res=0;

while(l1||l2){

int val1=l1?l1->val:0;

int val2=l2?l2->val:0;

int sum=val1+val2+res;

res=sum/10;

cur->next=new ListNode(sum%10);

cur=cur->next;

if(l1)

l1=l1->next;

if(l2)

l2=l2->next;

}

if(res)

cur->next=new ListNode(1);

return p->next;

}

};

顺序链表存储相加

思路:这道题和第2题类似,但是链表是从前往后遍历,加法却要从最低位相加,所以可以考虑改用栈来存储放进来的数据。

/**

* Definition for singly-linked list.

* struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

* };

*/

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

stack s1, s2;

while (l1) {

s1.push(l1->val);

l1 = l1->next;

}

while (l2) {

s2.push(l2->val);

l2 = l2->next;

}

int sum = 0;

ListNode *res = new ListNode(0);

while (!s1.empty() || !s2.empty()) {

if (!s1.empty()) {

sum += s1.top();

s1.pop();

}

if (!s2.empty()) {

sum += s2.top();

s2.pop();

}

res->val = sum % 10;

ListNode *cur = new ListNode(sum / 10);

cur->next = res;

res = cur;

sum /= 10;

}

return res->val == 0 ? res->next : res;

}

};

移除链表元素

思路:直接递归调用到链表末尾,然后回来,需要删除的元素将链表next指针指向下一个元素即好。

/**

* 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) {

if(!head) return NULL;

head->next=removeElements(head->next,val);

return head->val==val?head->next:head;

}

};

删除排序链表中的重复元素

思路:递归查找,如果head的值存在且相等,那么while循环跳过后面所有值相等的结点,如果后面if还有值相等则继续进行递归。如果最后到head的值不同后,返回到head即可。<这种方式比新建链表存储时间负责度高很多>

/**

* 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) return head;

if (head->next && head->val == head->next->val) {

while (head->next && head->val == head->next->val) {

head = head->next;

}

return deleteDuplicates(head->next);

}

head->next = deleteDuplicates(head->next);

return head;

}

};

删除顺序链表中的重复元素

思路:head结点的值和身后结点的值进行比较,如果值相同,则返回后面一个结点。最后回溯递归调用删除重复结点。

/**

* 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||!head->next) return head;

head->next=deleteDuplicates(head->next);

return (head->val==head->next->val)?head->next:head;

}

};


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决mybatis批量更新(update foreach)失败的问题
下一篇:Spring Boot 结合 aop 实现读写分离
相关文章

 发表评论

暂时没有评论,来抢沙发吧~