23 四数相加 II

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。

例如:

输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

输出:
2

解释:
两个元组如下:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

分析

显然如果暴力解题,复杂度会到达恐怖的O(n^4),显然是不合要求的。

然后又想了下,分为两组的话,可以将复杂度降到O(n^2)。

本来觉得这个复杂度还不是最优的,但实在想不到如何再优化,结果网上搜一下,结果都是这个O(n^2)的算法。

思路就是,HashMap存前两个数组能组成的数字及其组成的次数,再遍历后两个数组,查看HashMap中是否存在两数和的相反数,如果存在,则记录出现次数,累加即为结果。

代码

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        HashMap<Integer,Integer> map = new HashMap<>();

        int count = 0;
        for(int i=0;i<A.length;i++){
            for(int j=0;j<B.length;j++){
                map.put(A[i]+B[j],map.getOrDefault(A[i]+B[j],0)+1);
            }
        }

        for(int i=0;i<C.length;i++){
            for(int j=0;j<D.length;j++){
                count+= map.getOrDefault(-C[i]-D[j],0);
            }
        }
        return count;
    }
}
<think>嗯,用户问怎么计算两相加,听起来挺基础的,但我得仔细想想怎么解释清楚。首先,得确定用户的基础,可能是个刚开始学学的小朋友,或者需要复习的成年人。不管怎样,我需要从最简单的概念讲起。 首先,两相加的基本概念,应该用例子来说明,比如1+1=2这样的,然后逐步增加难度。可能还要分整和小的情况,不过用户可能先想知道整的加法。然后,可能需要解释进位,比如9+5=14,这时候十位进1,个位是4。不过如果是简单的个位相加,可能不需要进位,但用户可能需要知道如何处理进位的情况。 接下来,可能需要分步骤来说,比如对齐位,从个位开始加,进位处理。如果是多位相加,比如23+45,先个位3+5=8,十位2+4=6,得到68。如果是更大的,比如58+67,个位8+7=15,这时候要进位,个位写5,十位5+6+1=12,所以结果是125。这样的例子应该能说明进位的过程。 然后,可能需要提到小的情况,比如对齐小点,然后同样从右到左相加,注意进位。例如3.14+2.56,个位3+2=5,十分位1+5=6,百分位4+6=10,所以百分位是0,进1到十分位,结果变成5.70,也就是5.7。 还要考虑负的情况吗?比如-5+3,这时候可能需要解释轴上的移动,或者绝对值相减,符号取较大的绝对值的符号。不过用户可能暂时不需要负,但如果有提到的话,应该简单说明。 另外,可能用户会混淆加法和减法的符号,需要强调加号的使用。还有交换律,a+b=b+a,可能对用户理解有帮助,不过不一定需要深入,但可以提一下。 最后,可能给出一些练习题,让用户自己尝试,比如12+34,56+78,或者有进位的如99+1。然后提醒检查计算是否正确,可以通过减法验证,或者重新计算一遍。 总之,步骤应该是:1. 对齐位;2. 从右到左逐位相加;3. 处理进位;4. 得到结果。同时举例说明不同情况,包括进位和小点对齐的情况。可能还需要注意用户是否有其他特殊情况的需求,比如更大的或者不同进制的加法,但通常用户问的是十进制的基础加法。</think>计算两个相加需要遵循基本的算术规则。以下是详细步骤: --- ### **一、基本概念** 两相加学表达式为: $$ a + b = c $$ 其中,$a$ 和 $b$ 是加,$c$ 是它们的和。 --- ### **二、计算步骤(以整为例)** #### 1. **对齐位** 将两个的**个位、十位、百位等对齐**。例如: ``` 23 + 45 ------ ``` #### 2. **从右向左逐位相加** - **个位相加**:$3 + 5 = 8$ - **十位相加**:$2 + 4 = 6$ 结果为:$23 + 45 = 68$。 --- #### 3. **处理进位(如有)** 如果某一位的和 $\geq 10$,需向高位进位。例如: ``` 58 + 67 ------ ``` - **个位**:$8 + 7 = 15$,保留 $5$,向十位进 $1$ - **十位**:$5 + 6 + 1 = 12$,保留 $2$,向百位进 $1$ - **百位**:$0 + 0 + 1 = 1$ 结果为:$58 + 67 = 125$。 --- ### **三、特殊情况** #### 1. **小相加** 需对齐小点后逐位相加: ``` 3.14 +2.56 ------ ``` - **百分位**:$4 + 6 = 10$,保留 $0$,向十分位进 $1$ - **十分位**:$1 + 5 + 1 = 7$ - **个位**:$3 + 2 = 5$ 结果为:$3.14 + 2.56 = 5.70$。 #### 2. **负相加** 利用轴或绝对值规则: - $-5 + 3 = -2$(相当于从 $-5$ 向右移动 $3$ 个单位) - $-4 + (-6) = -10$(绝对值相加,符号不变) --- ### **四、验证结果** 通过以下方法检查正确性: 1. **逆运算验证**:用减法验证,例如 $125 - 67 = 58$。 2. **重新计算**:换顺序相加,例如 $67 + 58$。 --- ### **五、练习示例** 1. $12 + 34 = 46$ 2. $99 + 1 = 100$(注意连续进位) 通过逐步对齐位、处理进位,即可准确计算两之和。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知所起 一往而深

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值