翻倍以链表形式表示数字(递归) - 教程
给你一个 非空 链表的头节点 head
,表示一个不含前导零的非负数整数。
将链表 翻倍 后,返回头节点head
。
示例 1:
输入:head = [1,8,9]
输出:[3,7,8]
解释:上图中给出的链表,表示数字 189 。返回的链表表示数字 189 * 2 = 378 。
示例 2:
输入:head = [9,9,9]
输出:[1,9,9,8]
解释:上图中给出的链表,表示数字 999 。返回的链表表示数字 999 * 2 = 1998 。
提示:
- 链表中节点的数目在范围
[1, 104]
内 0 <= Node.val <= 9
- 生成的输入满足:链表表示一个不含前导零的数字,除了数字
0
本身。
(1)看到这道题我首先想到能不能做一个函数模拟十进制的进位,于是我们定义一个doDouble(ListNode* head,int* cap)函数来完成我们数字翻倍并进位的操作,其中head是给定链表的头节点,cap是存储该向下一位进位多少。
(2)如果链表为空则结束函数。
(3)由于进位是无数个相同的计算方法,且有一个回溯的过程(从低位到高位),我们采用递归的方法,我们只需要考虑我们这一位需要干什么。我们创建一个int val用于存储得到的进位值,将地址传给前一位帮我们计算进位值。我们这一位还需要做的就是算出需要向下一位进位多少,则先算出翻倍后head->val = head->val*2+ (进位值)val,再进行除法和模的操作得出进位值和本位的值。
(4)接下来到我们的主函数中,我们还需要创建一个val存储进位值,如果val==0说明没有进位,当前这个head就是头节点,不等于0我们则需要闯进新的头节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
void doDouble(ListNode* head,int* cap){
if(head==NULL){
return;//如果链表为空则结束函数
}
int val;//后一位得到的进位
doDouble(head->next,&val);
head->val = head->val*2+val;//先的出翻倍的值
*cap = head->val/10;//进位多少
head->val %=10;//当前位数值为多少
}
public:
ListNode* doubleIt(ListNode* head) {
int val;//存放进位
doDouble(head,&val);
if(val==0){
return head;//不尽位则头节点就是head
}
return new ListNode(val,head);//如果头节点进位,则生成一个新的头节点,值为进位多少val
}
};