1.分数转化为小数
题目要求
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。
如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 104 。
思路
莫得思路
先看图
题目要求根据给定的分子和分母,将分数转成整数或小数。由于给定的分子和分母的取值范围都是 [−231,231−1],为了防止计算过程中产生溢出,需要将分子和分母转成 64 位整数表示。
将分数转成整数或小数,做法是计算分子和分母相除的结果。可能的结果有三种:整数、有限小数、无限循环小数。
如果分子可以被分母整除,则结果是整数,将分子除以分母的商以字符串的形式返回即可。
如果分子不能被分母整除,则结果是有限小数或无限循环小数,需要通过模拟长除法的方式计算结果。为了方便处理,首先根据分子和分母的正负决定结果的正负(注意此时分子和分母都不为 0),然后将分子和分母都转成正数,再计算长除法。
计算长除法时,首先计算结果的整数部分,将以下部分依次拼接到结果中:
如果结果是负数则将负号拼接到结果中,如果结果是正数则跳过这一步;
将整数部分拼接到结果中;
将小数点拼接到结果中。
完成上述拼接之后,根据余数计算小数部分。
计算小数部分时,每次将余数乘以 10,然后计算小数的下一位数字,并得到新的余数。重复上述操作直到余数变成 0 或者找到循环节。
如果余数变成 0,则结果是有限小数,将小数部分拼接到结果中。
如果找到循环节,则找到循环节的开始位置和结束位置并加上括号,然后将小数部分拼接到结果中。
如何判断是否找到循环节?注意到对于相同的余数,计算得到的小数的下一位数字一定是相同的,因此如果计算过程中发现某一位的余数在之前已经出现过,则为找到循环节。为了记录每个余数是否已经出现过,需要使用哈希表存储每个余数在小数部分第一次出现的下标。
class Solution:
def fractionToDecimal(self, numerator: int, denominator: int) -> str:
if numerator % denominator == 0:
return str(numerator//denominator)
ans = []
if numerator / denominator < 0:
ans.append('-')
numerator = abs(numerator)
denominator = abs(denominator)
ans.append(str(numerator//denominator))
ans.append('.')
left = numerator % denominator
leftMap = {}
while left and left not in leftMap:
leftMap[left] = len(ans)
left *= 10
print(left)
ans.append(str(left//denominator))
left = left % denominator
if left != 0:
ans.insert(leftMap[left],'(')
ans.append(')')
return ''.join(ans)
2.两整数之和
题目要求
给你两个整数 a 和 b ,不使用 运算符 + 和 - ,计算并返回两整数之和。
示例 1:
输入:a = 1, b = 2
输出:3
示例 2:
输入:a = 2, b = 3
输出:5
思路
。。。
class Solution:
def getSum(self, a: int, b: int) -> int:
num = [a,b]
return sum(num)
其实肯定是可以通过二进制的位运算来完成的,就是不知道咋整
MASK1 = 4294967296 # 2^32
MASK2 = 2147483648 # 2^31
MASK3 = 2147483647 # 2^31-1
class Solution:
def getSum(self, a: int, b: int) -> int:
a %= MASK1
b %= MASK1
while b != 0:
carry = ((a & b) << 1) % MASK1
a = (a ^ b) % MASK1
b = carry
if a & MASK2: # 负数
return ~((a ^ MASK2) ^ MASK3)
else: # 正数
return a
#作者:力扣官方题解