- Pow(x, n),数值的整数次方 快速幂">Pow(x, n),数值的整数次方 快速幂
- 递归乘法">递归乘法
- 基本计算器">基本计算器
- 基本计算器 II">基本计算器 II
- 两整数之和">两整数之和
- 水壶问题">水壶问题
- 多数元素*(摩尔投票法)">多数元素*(摩尔投票法)
- 快乐数">快乐数
- 只出现一次的数字">只出现一次的数字
- 数组中数字出现的次数*">数组中数字出现的次数*
- 除自身以外数组的乘积,构建乘积数组">除自身以外数组的乘积,构建乘积数组
- 把数字翻译成字符串">把数字翻译成字符串
- 最小数">最小数
- 最大数">最大数
- 扑克牌中的顺子">扑克牌中的顺子
- 丑数">丑数
- 丑数 II">丑数 II
- 用两个栈实现队列">用两个栈实现队列
- 比较版本号">比较版本号
Pow(x, n),数值的整数次方 快速幂
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。
输入:x = 2.00000, n = 10
输出:1024.00000
输入:x = 2.10000, n = 3
输出:9.26100
输入:x = 2.00000, n = -2
输出:0.25000
解释:2-2 = 1/22 = 1/4 = 0.25
class Solution(object):def myPow(self, x, n):if x == 0.0:return 0.0# 当n < 0 时:把问题转化至n≥0 的范围内,即执行x = 1/x,n = - nif n < 0:x = 1 / xn = -nres = 1while n:if n & 1:res = res * xx = x * xn = n >> 1# n = n // 2return res
- 当x = 0.0时:直接返回0.0,以避免后续1除以0操作报错。分析:数字0的正数次幂恒为0;0的0次幂和负数次幂没有意义,因此直接返回0.0即可
- 初始化res = 1
- 当n < 0 时:把问题转化至n≥0 的范围内,即执行x = 1/x,n = - n
- 循环计算:当 x=0 时跳出
- 当n & 1 = 1时:将当前x乘入res(即 res = res * x )
- 执行x = x * x
- 执行n右移一位(即 n >>= 1)
-
递归乘法
递归乘法。 写一个递归函数,不使用 * 运算符, 实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。
输入:A = 1, B = 10
输出:10
输入:A = 3, B = 4
输出:12class Solution(object):def multiply(self, A, B):# 将其中的B拆成2进制,那么每一位对应的就是2的幂,那么可以由A+=A得到res = 0while B:# 当前位为奇数时,加一次 A# 当前位为 偶数时,加两次 Aif B & 1:res += A# B 不断地向右移动一位计算,直至B为0B = B >> 1if B:A += Areturn res
基本计算器
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
输入:s = “1 + 1”
输出:2
输入:s = “ 2-1 + 2 “
输出:3
输入:s = “(1+(4+5+2)-3)+(6+8)”
输出:23class Solution(object):def calculate(self, s):# 用栈保存遇到左括号时前面计算好了的运算符stack = [1]# sign表示当前运算符sign = 1# res表示左边表达式除去栈内保存元素的计算结果res = 0i = 0while i < len(s):if s[i] == ' ':i += 1# 如果是+用sign记录下来elif s[i] == '+':sign = stack[-1]i += 1# 如果是-用sign记录下来elif s[i] == '-':sign = -stack[-1]i += 1# 如果是(,将当前sign记录到栈elif s[i] == '(':stack.append(sign)i += 1# 如果是),将sign剔除elif s[i] == ')':stack.pop()i += 1else:# 为了解决可能出现连续的数字num = 0# 下标没越界且s[i]是数字while i < len(s) and s[i].isdigit():num = num * 10 + int(s[i])i += 1# num加上sign运算符更新到res中res += num * signreturn res
基本计算器 II
注意:这个题一定要切到Python3提交,2过不了
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
输入:s = “3+2*2”
输出:7
输入:s = “ 3/2 “
输出:1
输入:s = “ 3+5 / 2 “
输出:5class Solution:def calculate(self, s: str) -> int:stack = []pre_ops = '+'num = 0i = 0while i < len(s):if s[i].isdigit():num = 10 * num + int(s[i])if i == len(s) - 1 or s[i] in '+-*/':if pre_ops == '+':stack.append(num)elif pre_ops == '-':stack.append(-num)elif pre_ops == '*':stack.append(stack.pop() * num)elif pre_ops == '/':stack.append(int(stack.pop() / num))pre_ops = s[i]num = 0i += 1return sum(stack)
两整数之和
不使用运算符 + 和 - ,计算两整数 a 、b 之和。
输入: a = 1, b = 2
输出: 3
输入: a = -2, b = 3
输出: 1class Solution:# 根本就不会def getSum(self, a: int, b: int) -> int:a &= 0xFFFFFFFFb &= 0xFFFFFFFFwhile b:carry = a & ba ^= bb = ((carry) << 1) & 0xFFFFFFFF# print((a, b))return a if a < 0x80000000 else ~(a^0xFFFFFFFF)
水壶问题
有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?
如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。
你允许:
装满任意一个水壶
清空任意一个水壶
从一个水壶向另外一个水壶倒水,直到装满或者倒空
输入: x = 3, y = 5, z = 4
输出: True
输入: x = 2, y = 6, z = 5
输出: Falseclass Solution:def canMeasureWater(self, jug1Capacity, jug2Capacity, targetCapacity):# 方法一:贝祖定理x = jug1Capacityy = jug2Capacityz = targetCapacityif z == 0:return Trueif x == 0:if z == y:return Trueelse:return Falseif y == 0:if z == x:return Trueelse:return Falseif z > x + y:return False# 而贝祖定理告诉我们,ax+by=z有解当且仅当z是x, y的最大公约数的倍数。因此我们只需要找到x,y的最大公约数并判断z是否是它的倍数即可。if x > y:x, y = y, xif y % x == 0:if z % x == 0:return Trueelse:return Falseelse:if y % (y % x) == 0:if z % (y % x) == 0:return Trueelse:return Falseelse:return True# 方法二:调包侠x = jug1Capacityy = jug2Capacityz = targetCapacityif x + y < z:return Falseif x == 0 or y == 0:return z == 0 or x + y == zreturn z % math.gcd(x, y) == 0
多数元素*(摩尔投票法)
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
输入:[3,2,3]
输出:3
输入:[2,2,1,1,1,2,2]
输出:2class Solution(object):def majorityElement(self, nums):count = 0major = 0for i in nums:if count == 0:major = iif i == major:count += 1else:count -= 1return major
快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 true ;不是,则返回 false 。
输入:19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
输入:n = 2
输出:falseclass Solution(object):def isHappy(self, n):dicts = {}while True:n = sum(int(i) ** 2 for i in str(n))if n == 1:return Trueif n in dicts:return Falsedicts[n] = 1
只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
输入: [2,2,1]
输出: 1
输入: [4,1,2,1,2]
输出: 4class Solution(object):def singleNumber(self, nums):# 异或,当同位相同时结果为0,不同结果为1res = 0for i in nums:res ^= ireturn res
数组中数字出现的次数*
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]class Solution(object):def singleNumbers(self, nums):res = 0 # 所有数字异或的结果a = 0b = 0for i in nums:res ^= i# 找到第一位不是0的h = 1while(res & h == 0):h <<= 1for n in nums:# 根据该位是否为0将其分为两组if (h & n == 0):a ^= nelse:b ^= nreturn [a, b]
除自身以外数组的乘积,构建乘积数组
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
输入: [1,2,3,4]
输出: [24,12,8,6]class Solution(object):def productExceptSelf(self, nums):# 根据表格的主对角线,可将表格分为 上三角 和 下三角 两部分。分别迭代计算下三角和上三角两部分的乘积res = [1] * len(nums)for i in range(1, len(nums)):res[i] = res[i-1] * nums[i-1] # 下三角tmp = 1for j in range(len(nums) - 2, -1, -1):tmp *= nums[j+1] # 上三角res[j] *= tmp # 下三角 * 上三角return res
把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是”bccfi”, “bwfi”, “bczi”, “mcfi”和”mzi”class Solution(object):def translateNum(self, num):# 方法一:从左向右遍历s = str(num)a = b = 1for i in range(2, len(s) + 1):# 如果当前值和前一个数字能组成10到25的数if "10" <= s[i-2:i] <= "25":c = a + belse:c = ab = aa = creturn a
最小数
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
输入: [10,2]
输出: “102”
输入: [3,30,34,5,9]
输出: “3033459”class Solution(object):def minNumber(self, nums):if len(nums)==0:return ""# 将元素都转换成字符串for i in range(len(nums)):nums[i] = str(nums[i])# 冒泡排序。。for i in range(len(nums)):for j in range(i+1, len(nums)):if nums[i] + nums[j] > nums[j] + nums[i]:nums[i], nums[j] = nums[j], nums[i]return "".join(nums)
最大数
给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。
输入:nums = [10,2]
输出:”210”
输入:nums = [3,30,34,5,9]
输出:”9534330”class Solution(object):def largestNumber(self, nums):# 方法一:堆排序s = []for i in nums:tmp = (str(i)*10)[:10]heapq.heappush(s, [-int(tmp), str(i)])ans = ""while s:ans += heapq.heappop(s)[1]return str(int(ans))# 方法二:冒泡排序for i in range(len(nums)):for j in range(len(nums) - i - 1):if str(nums[j]) + str(nums[j + 1]) > str(nums[j + 1]) + str(nums[j]):nums[j], nums[j + 1] = nums[j + 1], nums[j]s = ''if nums[-1] == 0:return('0')for i in nums:s = str(i) + sreturn s
扑克牌中的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
输入: [1,2,3,4,5]
输出: True
输入: [0,0,1,2,5]
输出: Trueclass Solution(object):# 排序后首先排除0,然后累加相邻元素差,这是为了在相邻元素差为0(即相邻元素相等)时,直接返回False,如果累加差值<5,则为顺子。nums.sort()count = 0for i in range(4):if nums[i] == 0:continueif nums[i+1] == nums[i]:return Falsecount += nums[i+1] - nums[i]if count < 5:return Truereturn False
丑数
给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
输入:n = 6
输出:true
解释:6 = 2 × 3
输入:n = 8
输出:true
解释:8 = 2 × 2 × 2class Solution(object):def isUgly(self, n):if n <= 0:return Falsefactors = [2, 3, 5]for factor in factors:while n % factor == 0:n //= factorreturn n == 1
丑数 II
给你一个整数 n ,请你找出并返回第 n 个 丑数 。
丑数 就是只包含质因数 2、3 和/或 5 的正整数。
输入:n = 10
输出:12
解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。
输入:n = 1
输出:1
解释:1 通常被视为丑数。class Solution(object):def nthUglyNumber(self, n):if n < 0:return 0dp = [1] * nindex2, index3, index5 = 0, 0, 0for i in range(1, n):dp[i] = min(2 * dp[index2], 3 * dp[index3], 5 * dp[index5])if dp[i] == 2 * dp[index2]:index2 += 1if dp[i] == 3 * dp[index3]:index3 += 1if dp[i] == 5 * dp[index5]:index5 += 1return dp[n - 1]
用两个栈实现队列
class CQueue:def __init__(self):self.A, self.B = [], []def appendTail(self, value):self.A.append(value)def deleteHead(self):if self.B: return self.B.pop()if not self.A: return -1while self.A:self.B.append(self.A.pop())return self.B.pop()
比较版本号
给你两个版本号 version1 和 version2 ,请你比较它们。
输入:version1 = “1.01”, version2 = “1.001”输出:0
解释:忽略前导零,”01” 和 “001” 都表示相同的整数 “1”
输入:version1 = “1.0”, version2 = “1.0.0”
输出:0
解释:version1 没有指定下标为 2 的修订号,即视为 “0”
输入:version1 = “0.1”, version2 = “1.1”
输出:-1
解释:version1 中下标为 0 的修订号是 “0”,version2 中下标为 0 的修订号是 “1” 。0 < 1,所以 version1 < version2
输入:version1 = “1.0.1”, version2 = “1”
输出:1 ```python class Solution: def compareVersion(self, version1, version2):# 方法一:补齐元素再比大小nums1 = version1.split('.')nums2 = version2.split('.')# 补齐长度if len(nums1) > len(nums2):nums2 = nums2 + ['0'] * (len(nums1)-len(nums2))if len(nums2) > len(nums1):nums1 = nums1 + ['0'] * (len(nums2) - len(nums1))# 分别比较两个版本号每一位的大小for i in range(len(nums1)):if int(nums1[i]) > int(nums2[i]):return 1elif int(nums1[i]) < int(nums2[i]):return -1else:continuereturn 0
class Solution: def compareVersion(self, version1, version2):
# 方法二:与方法一类似,只是不补齐,两个复杂度一样都不是最优解nums1 = version1.split('.')nums2 = version2.split('.')for i in range(max(len(nums1), len(nums2))):# 分别比较两个版本号每一位的大小if i < len(nums1):i1 = int(nums1[i])else:i1 = 0if i < len(nums2):i2 = int(nums2[i])else:i2 = 0if i1 > i2:return 1elif i1 < i2:return -1else:continuereturn 0
<a name="lds2J"></a>## 小数循环节```pythondef xun_huan_jie(a, b):# 不再判断余数是否为0,而是把所有的小数都看为循环小数,0.5可以看为:0.5[0],这样就统一处理了zheng = str(a // b) ## 商的整数部分shang = "" ## 商的小数部分yu = [a % b]while True:# 求商x = (yu[-1] * 10) // b# 求余y = (yu[-1] * 10) % bshang += str(x)yu.append(y)i = yu.index(yu[-1])if i != len(yu) - 1:shang = shang[:i] + "[" + shang[i:] + "]"breakr = zheng + "." + shang# 如果以[0]结尾,就删去if r.endswith("[0]"):r = r[:-3]# 如果没有小数部分,小数点也删去if r.endswith("."):r = r[:-1]return rif __name__ == '__main__':print(xun_huan_jie(100, 5))print(xun_huan_jie(1, 8))print(xun_huan_jie(1, 7))print(xun_huan_jie(12345, 1700))200.1250.[142857]7.26[1764705882352941]
