变量等价-解决数字字符串的加法与乘法 2020-08-13

数字字符串的加法与乘法

1.数字字符串加法

给定两个长度可以上千上万的数字字符串s1, s2,把它们按数值相加,将结果以字符串形式返回
如"123" + "123" = "246"

这个实现是比较基础的,我们【模拟竖式加法】,从低位到高位取对应字符,转为int相加,一步一步模拟加法计算即可

  • 做法1:【静态补0】先把两个字符串长度补齐,短的在前面补0,补齐后方便统一处理
class Solution:
    def addStrings(self, num1: str, num2: str) -> str:
        str1, str2 = num1, num2
        l1, l2 = len(str1), len(str2)
        # 补齐长度,不足就补0
        if l1 < l2:
            str1 = '0' * (l2-l1) + str1
        elif l1 > l2:
            str2 = '0' * (l1-l2) + str2
        
        res = ''
        carrier = 0
        for index in range(len(str1)-1, -1, -1):
            temp = int(str1[index]) + int(str2[index]) + carrier
            mod = temp % 10
            carrier = temp // 10
            res = str(mod) + res
        # 跳出循环之后处理一下carrier
        if carrier != 0:
            res = str(carrier) + res
        return res
  • 做法2:【地位等价,动态补0 -> 优质模板】使用两个指针指向num1和num2的末端。这时,指针和carrier地位平等,只要任意一处有值,就要加入temp_res;没有值则不加(等同于+0)
    这个写法比较优美,思维更加灵活,可泛化
class Solution:
    def addStrings(self, num1: str, num2: str) -> str:
        i, j = len(num1) - 1, len(num2) - 1
        carrier = 0
        res = ''
        while i >= 0 or j >= 0 or carrier != 0:
            temp_res = 0
            if i >= 0:
                temp_res += int(num1[i])
            if j >= 0:
                temp_res += int(num2[j])
            temp_res += carrier
            
            mod = temp_res % 10
            carrier = temp_res // 10
            res = str(mod) + res

            i -= 1
            j -= 1
        return res

由本写法泛化的 leetcode面试题 02.05. 链表求和
链表倒序存放,返回求和后的倒序链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        ans_pre = ListNode('')
        poiter = ans_pre
        carrier = 0
        while l1 or l2 or carrier != 0:
            temp_val = 0
            if l1:
                temp_val += l1.val
                l1 = l1.next
            if l2:
                temp_val += l2.val
                l2 = l2.next
            temp_val += carrier

            mod = temp_val % 10
            carrier = temp_val // 10

            poiter.next = ListNode(mod)
            poiter = poiter.next
        poiter.next = None
        return ans_pre.next

2.字符串乘法

竖式乘法里面,先拿乘数的每一位,乘以被乘数,然后把所有乘积位移后相加。也就是说,相比字符串加法,前面多了一个乘法过程

class Solution:
    def multiply(self, num1: str, num2: str) -> str:
        # 【优化点】用字典来保存乘数num2的每一个digit乘以被乘数num1的结果,可以在一定程度上避免重复计算
        temp_res_dict = dict()

        res = ''
        cnt = 0
        for i in num2[::-1]:
            if i in temp_res_dict:
                temp_res = temp_res_dict[i]
            else:
                # 乘数的一个digit乘以整个被乘数
                carrier = 0
                temp_res = ''
                for j in num1[::-1]:
                    temp = int(i) * int(j) + carrier
                    mod = temp % 10
                    carrier = temp // 10
                    temp_res = str(mod) + temp_res
                if carrier != 0:
                    temp_res = str(carrier) + temp_res
                temp_res_dict[i] = temp_res
            res = self.add(res, temp_res+'0'*cnt)
            cnt += 1
        
        if res and res[0] == '0':
            return '0'
        return res

    # 字符串相加
    def add(self, str1, str2) -> str:
        l1, l2 = len(str1), len(str2)
        # 补齐长度,不足就补0
        if l1 < l2:
            str1 = '0' * (l2-l1) + str1
        elif l1 > l2:
            str2 = '0' * (l1-l2) + str2
        
        res = ''
        carrier = 0
        for index in range(len(str1)-1, -1, -1):
            temp = int(str1[index]) + int(str2[index]) + carrier
            mod = temp % 10
            carrier = temp // 10
            res = str(mod) + res
        if carrier != 0:
            res = str(carrier) + res
        return res

小结

字符串相加、链表相加,本质上都要按位模拟竖式运算,涉及到对应位数求和+进位

做法2将digit和carrier一视同仁,地位平等,存在任意一个就处理。这样就将复杂的长度判断、进位判断等条件判断收敛到一处,即只判断是否存在digit or carrier,大大简化了问题,提升代码可写可读性

你可能感兴趣的:(变量等价-解决数字字符串的加法与乘法 2020-08-13)