leetcode
leetcode 301 ~ 350
给单链表加一

给单链表加一

难度:

标签:

题目描述

代码结果

运行时间: 24 ms, 内存: 0.0 MB


/*
 * 题目思路:
 * 通过Java Stream处理链表加一。首先将链表转换为列表,
 * 然后对列表进行加一处理,再将列表转换回链表。
 */
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
 
class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}
 
public class AddOneToListStream {
    // 将链表转换为列表
    private static List<Integer> listNodeToList(ListNode head) {
        List<Integer> list = new ArrayList<>();
        while (head != null) {
            list.add(head.val);
            head = head.next;
        }
        return list;
    }
 
    // 将列表转换为链表
    private static ListNode listToListNode(List<Integer> list) {
        Collections.reverse(list);
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        for (int num : list) {
            current.next = new ListNode(num);
            current = current.next;
        }
        return dummy.next;
    }
 
    // 给链表加一的方法
    public static ListNode plusOne(ListNode head) {
        List<Integer> list = listNodeToList(head);
        Collections.reverse(list);
        List<Integer> result = new ArrayList<>();
        int carry = 1;
        for (int num : list) {
            int sum = num + carry;
            result.add(sum % 10);
            carry = sum / 10;
        }
        if (carry > 0) {
            result.add(carry);
        }
        return listToListNode(result);
    }
}
 

解释

方法:

这个题解使用了递归的方法。首先检查头节点的值是否为0,如果是则直接返回一个值为1的新节点。否则进入递归函数dfs,从链表的尾部开始,将每个节点的值加上一个进位值(初始为1),计算结果对10取模作为新的节点值,并将进位值传递给下一层递归。递归结束后,如果最后的进位值大于0,则在链表头部新增一个节点来容纳这个进位。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在头节点值为0的特殊情况下,您选择直接返回一个值为1的新节点而不是继续递归处理整个链表?
在头节点值为0的情况下,通常表示整个链表只有一个节点,且该节点的值为0。这是链表表示数字'0'的一种特殊情况。对于'加一'的操作,结果应该是'1'。继续递归处理整个链表在这种情况下是不必要的,因为我们已经知道结果只能是'1'。直接返回一个值为1的新节点是一种更简洁有效的处理方式。
🦆
递归函数中,如果当前节点为空,为什么返回的是进位值1而不是0?这是否与特定情况有关?
在递归函数中当当前节点为空时返回进位值1,是因为我们已经到达了链表的末尾,而整个操作是为了在链表末尾加一。在递归的最底层(即链表的最后一个节点之后),返回进位值1正是为了将这个'加一'操作传递回链表的最后一个节点。如果返回0,则表示没有进位,这与操作'加一'的目的不符。
🦆
在递归中处理每个节点时,您是如何确保链表的最终结果仍然保持单链表的顺序而不会发生逆转?
递归处理确保链表顺序不发生逆转的关键在于它处理节点的方式。递归函数是首先递归调用自身处理下一个节点,直到链表末尾,然后在递归返回阶段,从链表的末尾开始向前逐个处理节点的值和进位。这种自底向上的处理方式确保了虽然处理是从链表尾部开始,但链表的物理结构并没有改变,保持了单链表的顺序。
🦆
您提到如果最后的进位值大于0,则需要在链表头部新增一个节点。请问这种情况通常是在什么样的输入下发生?
如果最后的进位值大于0,通常发生在链表表示的数字每一位都是9的情况下。例如链表1 -> 9 -> 9,加一操作将其变为2 -> 0 -> 0,并产生一个新的进位1,这时需要在链表头部新增一个节点来容纳这个进位。这种情况是因为链表中的每一位加一后变成了10,需要向前进位。

相关问题

加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

 

示例 1:

输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。

示例 2:

输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。

示例 3:

输入:digits = [0]
输出:[1]

 

提示:

  • 1 <= digits.length <= 100
  • 0 <= digits[i] <= 9