栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

剑指offer--求1+2+…+n and 构建乘积数组 and 不用加减乘除做加法(从更深的角度考虑机器运算的方式)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

剑指offer--求1+2+…+n and 构建乘积数组 and 不用加减乘除做加法(从更深的角度考虑机器运算的方式)

题目1:

求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

思路:这一题如果没有限制条件那是非常简单的,但是题目要求我们不能使用关键字和乘除法,不过递归肯定还是这一道题的破解之处,我们只需要找到一个关键点,那就是什么时候递归截至。除了条件判断之外还有一个方法可以用来判断截至,那就是或运算和与运算,a&&b,如果a 是假的,&&后面的就不会执行,这就是我们的突破口。

代码:

class Solution:
    def __init__(self):
        self.res=0
    def sumNums(self, n: int) -> int:
        #通过逻辑and来进行递归的终止,n>1 and self.sumNums(n-1),
        #如果n>1不成立的话,那后面这个就不会运行
        n > 1 and self.sumNums(n - 1)
        self.res+=n
        return self.res

题目二:

给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

示例:

输入: [1,2,3,4,5]
输出: [120,60,40,30,24]

思路:如果可以使用除法的话那我们就会很简单的写出来这一道题,只需要在b数组的相应位置除以a数组中相应位置的值就可以了。但是题目中有限制,那我们这时候就会考虑暴力解法了,每一个值除了相应位置的不用乘,其他位置的依次相乘,这样很简单,但是肯定还是超时的,所以还要想其他的方法。这里我们可以使用一个数组的表格分区来写,将a数组和b数组写在一个表格中,第一次遍历表格的时候就算出来对角线左边的b[i]的值,倒着遍历回来的时候,再算出来真正的b[i]的值。

这里引用一下k神的图片

 第一次遍历的时候,依次算出来的是对角线左下角的绿色的a[i]的乘积,然后再倒着遍历一遍,将刚才b[i]的结果再乘上右上角部分的值,就得到最终的答案。

代码:

class Solution:
    def constructArr(self, a: List[int]) -> List[int]:
        #不可以使用除法,但是又不能直接暴力求解那样肯定是超时的
        #所以可以构建一个表格分区,分别求出来以对角线分开的上三角和下三角的值
        #根据需要将它们乘在一起
        length=len(a)
        temp=0
        b=[1]*length
        #计算下三角的值
        for i in range(1,length):
            b[i]=b[i-1]*a[i-1]
        #计算上三角的值
        for i in range(length-2,-1,-1):
            temp*=a[i+1]
            b[i]*=temp
    return b

题目三:

写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。

示例:

输入: a = 1, b = 1
输出: 2

思路:这一道题的思路可以参考数电中的加法器原理,s=a^b(不管进位的加法值为s,a和b的异或得到),c=a&b,进位的值是c,由a和b相与得到。然后我们就一直循环这个加法器,直到进位的值变成了0,就跳出循环,得到加法的值。

代码:

class Solution:
    def add(self, a: int, b: int) -> int:
        x = 0xffffffff
        a, b = a & x, b & x
        c=0
        n=0
        #循环过去直到进位为0
        while 1:
            c=(a&b)<<1 & x
            n=a^b 
            a=c
            b=n
            if c==0:
                break
        return n if n <= 0x7fffffff else ~(n ^ x)

python中负数需要注意的地方,和其他语言不太相同,上面的x也是这个原因

        '''

     Python,Java 等语言中的数字都是以 补码 形式存储的。但 Python 没有 int , long 等不同长度变量,即在编程时无变量位数的概念。

    获取负数的补码: 需要将数字与十六进制数 0xffffffff 相与。可理解为舍去此数字 32 位以上的数字(将 32 位以上都变为 00 ),从无限长度变为一个 32 位整数。

    返回前数字还原: 若补码 aa 为负数( 0x7fffffff 是最大的正数的补码 ),需执行 ~(a ^ x) 操作,将补码还原至 Python 的存储格式。 a ^ x 运算将 1 至 32 位按位取反; ~ 运算是将整个数字取反;因此, ~(a ^ x) 是将 32 位以上的位取反,1 至 32 位不变。

        '''

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/870899.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号