[LeetCode] Plus One Linked List 链表加一运算
Given a non-negative integer represented as non-empty a singly linked list of digits, plus one to the integer.
You may assume the integer do not contain any leading zero, except the number 0 itself.
The digits are stored such that the most significant digit is at the head of the list.
Example :
Input: [1,2,3]
Output: [1,2,4]
这道题给了我们一个链表,用来模拟一个三位数,表头是高位,现在让我们进行加1运算,这道题的难点在于链表无法通过坐标来访问元素,只能通过遍历的方式进行,而这题刚好让我们从链尾开始操作,从后往前,遇到进位也要正确的处理,最后还有可能要在开头补上一位。那么我们反过来想,如果链尾是高位,那么进行加1运算就方便多了,直接就可以边遍历边进行运算处理,那么我们可以做的就是先把链表翻转一下,然后现在就是链尾是高位了,我们进行加1处理运算结束后,再把链表翻转回来即可,参见代码如下:
解法一:
class Solution {
public:
ListNode* plusOne(ListNode* head) {
if (!head) return head;
ListNode *rev_head = reverse(head), *cur = rev_head, *pre = cur;
int carry = ;
while (cur) {
pre = cur;
int t = cur->val + carry;
cur->val = t % ;
carry = t / ;
if (carry == ) break;
cur = cur->next;
}
if (carry) pre->next = new ListNode();
return reverse(rev_head);
}
ListNode* reverse(ListNode *head) {
if (!head) return head;
ListNode *dummy = new ListNode(-), *cur = head;
dummy->next = head;
while (cur->next) {
ListNode *t = cur->next;
cur->next = t->next;
t->next = dummy->next;
dummy->next = t;
}
return dummy->next;
}
};
我们也可以通过递归来实现,这样我们就不用翻转链表了,通过递归一层一层的调用,最先处理的是链尾元素,我们将其加1,然后看是否有进位,返回进位,然后回溯到表头,加完进位,如果发现又产生了新的进位,那么我们在最开头加上一个新节点即可,参见代码如下:
解法二:
class Solution {
public:
ListNode* plusOne(ListNode* head) {
if (!head) return head;
int carry = helper(head);
if (carry == ) {
ListNode *res = new ListNode();
res->next = head;
return res;
}
return head;
}
int helper(ListNode *node) {
if (!node) return ;
int carry = helper(node->next);
int sum = node->val + carry;
node->val = sum % ;
return sum / ;
}
};
下面这种方法比较巧妙了,思路是遍历链表,找到右起第一个不为9的数字,如果找不到这样的数字,说明所有数字均为9,那么在表头新建一个值为0的新节点,进行加1处理,然后把右边所有的数字都置为0即可。举例来说:
比如1->2->3,那么第一个不为9的数字为3,对3进行加1,变成4,右边没有节点了,所以不做处理,返回1->2->4。
再比如说8->9->9,找第一个不为9的数字为8,进行加1处理变成了9,然后把后面的数字都置0,得到结果9->0->0。
再来看9->9->9的情况,找不到不为9的数字,那么再前面新建一个值为0的节点,进行加1处理变成了1,把后面的数字都置0,得到1->0->0->0。
解法三:
class Solution {
public:
ListNode* plusOne(ListNode* head) {
ListNode *cur = head, *right = NULL;
while (cur) {
if (cur->val != ) right = cur;
cur = cur->next;
}
if (!right) {
right = new ListNode();
right->next = head;
head = right;
}
++right->val;
cur = right->next;
while (cur) {
cur->val = ;
cur = cur->next;
}
return head;
}
};
最后这种解法是解法二的迭代写法,我们用到栈,利用栈的先进后出机制,就可以实现从后往前的处理节点,参见代码如下:
解法四:
class Solution {
public:
ListNode* plusOne(ListNode* head) {
stack<ListNode*> s;
ListNode *cur = head;
while (cur) {
s.push(cur);
cur = cur->next;
}
int carry = ;
while (!s.empty() && carry) {
ListNode *t = s.top(); s.pop();
int sum = t->val + carry;
t->val = sum % ;
carry = sum / ;
}
if (carry) {
ListNode *new_head = new ListNode();
new_head->next = head;
head = new_head;
}
return head;
}
};
类似题目:
参考资料:
https://leetcode.com/problems/plus-one-linked-list/
https://leetcode.com/discuss/111165/2-accepted-java-solution
https://leetcode.com/discuss/111205/simple-solution-use-recursion
https://leetcode.com/discuss/111157/9-lines-recursive-without-helper
https://leetcode.com/discuss/111155/java-stack-solution-with-inline-explanation
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Plus One Linked List 链表加一运算的更多相关文章
- [LeetCode] 369. Plus One Linked List 链表加一运算
Given a non-negative number represented as a singly linked list of digits, plus one to the number. T ...
- Leetcode 234 Palindrome Linked List 链表
判断链表是否是回文. 我直接将链表的一半进行倒置,然后将两半的链表进行比较 /** * Definition for singly-linked list. * struct ListNode { * ...
- Leetcode 206 Reverse Linked List 链表
将单向链表反转 完成如图操作,依次进行即可 1 2 3 /** * Definition for singly-linked list. * struct ListNode { * int val; ...
- [LeetCode]206. Reverse Linked List(链表反转)
Reverse a singly linked list. click to show more hints. Subscribe to see which companies asked this ...
- [LeetCode] 92. Reverse Linked List II 反向链表II
Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...
- LeetCode解题报告:Linked List Cycle && Linked List Cycle II
LeetCode解题报告:Linked List Cycle && Linked List Cycle II 1题目 Linked List Cycle Given a linked ...
- LeetCode 上最难的链表算法题,没有之一!
题目来源于 LeetCode 第 23 号问题:合并 K 个排序链表. 该题在 LeetCode 官网上有关于链表的问题中标注为最难的一道题目:难度为 Hard ,通过率在链表 Hard 级别目前最低 ...
- [LeetCode] 92. Reverse Linked List II_Medium tag: Linked List
Reverse a linked list from position m to n. Do it in one-pass. Note: 1 ≤ m ≤ n ≤ length of list. Exa ...
- 【python】Leetcode每日一题-旋转链表
[python]Leetcode每日一题-旋转链表 [题目描述] 给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例1: 输入:head = [1,2,3,4,5] ...
随机推荐
- SSRS ----环境配置,没有 ReportServer DB 怎么办?
今天项目进入报表开发阶段,按照习惯,打开报表管理器,发现提示下面的错误: 错误:报表服务器无法打开与报表服务器数据库的连接.所有请求和处理都要求与数据库建立连接. 这是怎么回事儿呢,经过排查,发现数据 ...
- 【中文分词】二阶隐马尔可夫模型2-HMM
在前一篇中介绍了用HMM做中文分词,对于未登录词(out-of-vocabulary, OOV)有良好的识别效果,但是缺点也十分明显--对于词典中的(in-vocabulary, IV)词却未能很好地 ...
- 列表组件抽象(2)-listViewBase说明
这是我写的关于列表组件的第2篇博客.前面的相关文章有: 1. 列表组件抽象(1)-概述 listViewBase是列表组件所有文件中最核心的一个,它抽象了所有列表的公共逻辑,将来如果有必要添加其它公共 ...
- C# 之 EXCEL导入导出
以下方式是本人总结的一些经验,肯定有很多种方法,在此先记下,留待以后补充... 希望朋友们一起来探讨相关想法,请在下方留言. A-1:EXCEL模板导出 非常简单,将EXCEL模板上传到项目中后,将其 ...
- 【神器】vimum在浏览器中键盘操作选择、复制、粘贴,键盘党的最爱
1.下载: http://files.cnblogs.com/files/quejuwen/vimum_extension_1_56.zip 2.开源:https://github.com/philc ...
- 【转】gc日志分析工具
性能测试排查定位问题,分析调优过程中,会遇到要分析gc日志,人肉分析gc日志有时比较困难,相关图形化或命令行工具可以有效地帮助辅助分析. Gc日志参数 通过在tomcat启动脚本中添加相关参数生成gc ...
- GJM : Unity3D HIAR -【 快速入门 】 五、导出 Android 工程、应用
导出 Android 工程.应用 在开始之前,请务必先保存您的工程,同时确认您已经安装 Android SDK 和 JDK.安装操作请参考以下链接: 搭建开发环境 Step 1. 设置 Android ...
- 让ABAP开发者愈加轻松的若干快捷键
引言 ABAP是一种和当代编程语言在许多方面有着相当不同的编程语言.ABAP的某些方面可能会让我们奇怪,为什么它会如此复杂?而它的某些方面又是那么杰出,给予了ABAP开发者们比其它任何语言更多的便利. ...
- Android 使用pull,sax解析xml
pull解析xml文件 1.获得XmlpullParser类的引用 这里有两种方法 //解析器工厂 XmlPullParserFactory factory=XmlPullParserFactory. ...
- IT菜鸟的生存指南(二)新手村任务
此文献给那些刚误入IT行业的小菜鸟们,此文无法教你如何"当上CEO,迎娶白富美",那是电视剧情.现实IT行业里危机重重,竞争激励.这里教你的是如何生存.生存.生存- 恭(不)喜(幸 ...