leetcode
leetcode 2251 ~ 2300
找出数组的串联值

找出数组的串联值

难度:

标签:

题目描述

You are given a 0-indexed integer array nums.

The concatenation of two numbers is the number formed by concatenating their numerals.

  • For example, the concatenation of 15, 49 is 1549.

The concatenation value of nums is initially equal to 0. Perform this operation until nums becomes empty:

  • If there exists more than one number in nums, pick the first element and last element in nums respectively and add the value of their concatenation to the concatenation value of nums, then delete the first and last element from nums.
  • If one element exists, add its value to the concatenation value of nums, then delete it.

Return the concatenation value of the nums.

 

Example 1:

Input: nums = [7,52,2,4]
Output: 596
Explanation: Before performing any operation, nums is [7,52,2,4] and concatenation value is 0.
 - In the first operation:
We pick the first element, 7, and the last element, 4.
Their concatenation is 74, and we add it to the concatenation value, so it becomes equal to 74.
Then we delete them from nums, so nums becomes equal to [52,2].
 - In the second operation:
We pick the first element, 52, and the last element, 2.
Their concatenation is 522, and we add it to the concatenation value, so it becomes equal to 596.
Then we delete them from the nums, so nums becomes empty.
Since the concatenation value is 596 so the answer is 596.

Example 2:

Input: nums = [5,14,13,8,12]
Output: 673
Explanation: Before performing any operation, nums is [5,14,13,8,12] and concatenation value is 0.
 - In the first operation:
We pick the first element, 5, and the last element, 12.
Their concatenation is 512, and we add it to the concatenation value, so it becomes equal to 512.
Then we delete them from the nums, so nums becomes equal to [14,13,8].
 - In the second operation:
We pick the first element, 14, and the last element, 8.
Their concatenation is 148, and we add it to the concatenation value, so it becomes equal to 660.
Then we delete them from the nums, so nums becomes equal to [13].
 - In the third operation:
nums has only one element, so we pick 13 and add it to the concatenation value, so it becomes equal to 673.
Then we delete it from nums, so nums become empty.
Since the concatenation value is 673 so the answer is 673.

 

Constraints:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 104

 

代码结果

运行时间: 26 ms, 内存: 16.2 MB


/*
 * 使用 Java Stream 实现上述算法。
 */
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ConcatenationValueStream {
    public static int findConcatenationValue(List<Integer> nums) {
        int concatenationValue = 0;
        while (nums.size() > 0) {
            if (nums.size() == 1) {
                concatenationValue += nums.remove(0);
            } else {
                String first = String.valueOf(nums.remove(0));
                String last = String.valueOf(nums.remove(nums.size() - 1));
                concatenationValue += Integer.parseInt(first + last);
            }
        }
        return concatenationValue;
    }
    public static void main(String[] args) {
        List<Integer> nums1 = Arrays.asList(7, 52, 2, 4);
        List<Integer> nums2 = Arrays.asList(5, 14, 13, 8, 12);
        System.out.println(findConcatenationValue(new ArrayList<>(nums1))); // 输出: 596
        System.out.println(findConcatenationValue(new ArrayList<>(nums2))); // 输出: 673
    }
}

解释

方法:

该题解通过双指针的方式从数组的两端开始操作。指针i初始化在数组的开头,指针j初始化在数组的末尾。在每次循环中,首先检查两个指针是否相遇。如果没有相遇,分别取出指针i和j所指向的数组元素,计算这两个数的串联值。为了计算串联值,首先需要确定将j所指元素拼接到i所指元素后面时,需要在i元素后面添加多少个零。这是通过不断地将j元素整除10直到为0来计算。然后将得到的串联值累加到最终答案中,并将两个指针向中心移动。当两个指针相遇时,如果数组长度为奇数,则将该中心元素直接累加到结果中。这样直到数组被完全遍历完毕。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在计算串联值时,你需要先将j所指元素的位数计算出来,然后将i所指元素乘以10的相应次数?
在进行数字的串联操作时,我们需要保证j元素整体排列在i元素的后面。为了实现这一点,在不使用字符串操作的情况下,我们必须了解j元素的位数,以便可以通过乘以相应的10的幂将i元素扩展到足够大,从而在不改变其原始数值的情况下,将j元素附加在其后。例如,如果i是123,j是4567,则i需要扩展为1230000后,再加上4567,得到最终的串联结果1234567。这种方法是数学上处理数字串联的直接方式。
🦆
在此题解中,当数组的元素个数为奇数时,最中间的元素直接加到结果中,这种处理方式是否会影响最终的串联值?
在这个算法中,当数组的元素个数为奇数时,最中间的元素被直接加到最终结果中,这是因为该元素没有与之配对的元素来形成串联值。这种处理方式是合理的,因为每个元素都应该被考虑在内。对于中间的元素,由于没有可以与之配对的另一个元素,所以其本身直接被加入最终结果是正确的处理方式,这不会错误地影响最终的串联值,而是确保了所有元素都被恰当地考虑了。
🦆
算法在处理两个指针相遇的情况时,有没有考虑到所有可能的边界条件,比如数组只有一个元素的情况?
该算法在设计时已经考虑了包括数组只有一个元素的情况在内的各种边界条件。当数组只有一个元素时,由于i和j初始指向同一位置(i = 0, j = 0),循环条件i < j不满足,因此循环不会执行,直接跳至检查i == j的条件。因为这里i等于j,所以单一元素直接被加入到最终的串联值中,正确处理了只有一个元素的情况。
🦆
双指针方法在这个问题中的效率如何,与其他可能的方法(如递归或单循环)相比有何优劣?
双指针方法在这个问题中效率较高,主要是因为它可以在单次遍历中处理完所有元素的串联。与递归方法相比,双指针避免了额外的调用栈开销,并且通常更易于理解和实现。与单循环相比,双指针方法可以更直观地在每次迭代中处理两个元素的串联,减少了可能的重复计算。总体而言,双指针方法在空间和时间效率上通常优于递归,并且在实现上比单循环更直观有效。

相关问题