目录
56. 从1到n整数中1出现的次数
输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含“1”的数字有1,10,11和12,其中“1”一共出现了5次。
样例
输入: 12
输出: 5
从1到abcdef,c位1的个数sum分为2部分:
sum += abc * 1000
if c > 1: sum += 1000; if c == 1: sum += def + 1
时间复杂度: O(log(n))
空间复杂度: O(1)
class Solution(object):
def numberOf1Between1AndN_Solution(self, n):
"""
:type n: int
:rtype: int
"""
ab=n
c=0
digital =1
defg=0
sum=0
while ab>0:
c=ab%10
ab//=10
sum+=ab*digital
if c==1:
sum+=(defg+1)
elif c>1:
sum+=digital
defg+=c*digital
digital*=10
return sum
58. 把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
例如输入数组[3, 32, 321],则打印出这3个数字能排成的最小数字321323。
样例
输入:[3, 32, 321]
输出:321323
注意:输出数字的格式为字符串。
直接引入cmp_to_key()定义比较规则,定义条件是key = cmp_to_key(lambda x,y:int(x+y)-int(y+x))
from functools import cmp_to_key
class Solution(object):
def printMinNumber(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
if nums==[]:
return ''
res=[]
for i in nums:
res.append(str(i))
res.sort(key = cmp_to_key(lambda x,y:int(x+y)-int(y+x)))
return ''.join(res)
59. 把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:
0翻译成”a”,1翻译成”b”,……,11翻译成”l”,……,25翻译成”z”。
一个数字可能有多个翻译。例如12258有5种不同的翻译,它们分别是”bccfi”、”bwfi”、”bczi”、”mcfi”和”mzi”。
请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。
样例
输入:"12258"
输出:5
问题的核心是动态规划,利用dp[i]表示到i位置所有可能得翻译方法,因此需要考虑s[i-2:i],即i-2位置和i1位置的组合数字,如果数字在‘10’---‘25’之间的话,可能有dp[i-1]+dp[i-2]种翻译方法,否则的话,dp[i]=dp[i-1],例如‘67’这样的数字,只有可能有一种翻译方式
其次考虑初始情况,即dp[0]=1,dp[1]=1,表示到当前位置的可能翻译方法,初始化为(n+1)维,因为n实际上是错开1维的。
class Solution:
def getTranslationCount(self, s):
"""
:type s: str
:rtype: int
"""
n=len(s)
dp=[0]*(n+1)
dp[0]=1;dp[1]=1
for i in range(2,n+1):
if '10'<=s[i-2:i]<='25':
dp[i]=dp[i-2]+dp[i-1]
else:
dp[i] = dp[i-1]
return dp[n]
60. 礼物的最大价值
在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。
你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格直到到达棋盘的右下角。
给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?
注意:
- m,n>0m,n>0
样例:
输入:
[
[2,3,1],
[1,7,1],
[4,6,1]
]
输出:19
解释:沿着路径 2→3→7→6→1 可以得到拿到最大价值礼物。
动态规划,相当于利用dp数组记录到当前位置的最大价值礼物,因为是相当于对grid的复制,因此初始化为n*m维即可,dp[0][0]中应该存放grid[0][0]的具体数值,第一行和第一列中从左往右,从上往下直接加即可,要注意行走路径只能向右或者向下
class Solution(object):
def getMaxValue(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
n = len(grid)
m = len(grid[0])
dp = [[0]*(m) for _ in range(n)]
dp[0][0] = grid[0][0]
for i in range(1,n):
dp[i][0] = dp[i-1][0]+grid[i][0]
for j in range(1,m):
dp[0][j] = dp[0][j-1]+grid[0][j]
for i in range(1,n):
for j in range(1,m):
dp[i][j] =max(dp[i-1][j],dp[i][j-1]) + grid[i][j]
return dp[-1][-1]
61. 最长不含重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
假设字符串中只包含从’a’到’z’的字符。
样例
输入:"abcabc"
输出:3
class Solution:
def longestSubstringWithoutDuplication(self, s):
"""
:type s: str
:rtype: int
"""
if not s:
return 0
n=len(s)
d=dict()
dp=[0]*n
res=0
for i in range (0,n):
if s[i] not in d.keys():
dp[i] =dp[i-1] + 1
else:
dist=i-d[s[i]]
if dist > dp[i-1]:
dp[i] = dp[i-1]+1
else:
dp[i] = dist
d[s[i]] = i
res=max(dp[i],res)
return res
62. 丑数
我们把只包含质因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含质因子7。
求第n个丑数的值。
样例
输入:5
输出:5
注意:习惯上我们把1当做第一个丑数。
class Solution(object):
def getUglyNumber(self, n):
"""
:type n: int
:rtype: int
"""
i=0;j=0;k=0
q=[1]
n-=1
while n:
n-=1
t = min(min(q[i]*2,q[j]*3),q[k]*5)
q.append(t)
if t==q[i]*2:
i+=1
if t==q[j]*3:
j+=1
if t==q[k]*5:
k+=1
# print(q)
return q[-1]
63. 字符串中第一个只出现一次的字符
在字符串中找出第一个只出现一次的字符。
如输入"abaccdeff"
,则输出b
。
如果字符串中不存在只出现一次的字符,返回#字符。
样例:
输入:"abaccdeff"
输出:'b'
class Solution:
def firstNotRepeatingChar(self, s):
"""
:type s: str
:rtype: str
"""
d={}
for i in range(len(s)):
if s[i] in d:
d[s[i]]+=1
else:
d[s[i]] =1
for i in range(len(s)):
if d[s[i]]== 1:
return s[i]
return '#'
64. 字符流中第一个只出现一次的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。
例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。
当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。
如果当前字符流没有存在出现一次的字符,返回#字符。
样例
输入:"google"
输出:"ggg#ll"
解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。
class Solution:
d=dict()
res=[]
def firstAppearingOnce(self):
"""
:rtype: str
"""
if self.res :
# print(self.res)
return self.res[0]
return '#'
def insert(self, char):
"""
:type char: str
:rtype: void
"""
if char not in self.d:
self.d[char] =1
else:
self.d[char] +=1
#print(self.d[char])
if self.d[char]>1:
#print('origial:',self.res)
while (self.res and self.d[self.res[0]] > 1):
self.res.pop(0)
else:
self.res.append(char)
#print('last:',self.res)
动态维护,当进来一个新字母中在字典中存储其出现的次数,如果出现超过2次,就要从队头开始依次pop先进来的元素,如果是新出现的字母的话直接push进去就可以了,注意返回的是队列的队头元素,即返回res[0]
65. 数组中的逆序对
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
输入一个数组,求出这个数组中的逆序对的总数。
样例
输入:[1,2,3,4,5,6,0]
输出:6
class Solution(object):
count = 0
def inversePairs(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
self.merge(nums)
return self.count
def merge(self, nums):
if len(nums) <= 1:
return nums
else:
mid = len(nums) // 2
left = self.merge(nums[:mid])
right = self.merge(nums[mid:])
return self.merge_sort(left, right)
def merge_sort(self, a, b):
la = len(a)
lb = len(b)
c = []
a.append(float('inf'))
b.append(float('inf'))
i, j = 0, 0
for x in range(0, la + lb):
if a[i] < b[j]:
c.append(a[i])
i += 1
else:
c.append(b[j])
j += 1
self.count += la - i
return c
66. 两个链表的第一个公共结点
输入两个链表,找出它们的第一个公共结点。
当不存在公共节点时,返回空节点。
样例
给出两个链表如下所示:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
输出第一个公共节点c1
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def findFirstCommonNode(self, headA, headB):
"""
:type headA, headB: ListNode
:rtype: ListNode
"""
i=headA;j=headB
while i!=j:
if i:i=i.next
else:i=headB
if j:j=j.next
else:j=headA
return i
A+C+B=B+C+A,要注意判断条件是if i,才能保证没有相交时两个指针都能到达Null,如果是if i.next的话。没有相交时二者会陷入死循还
67. 数字在排序数组中出现的次数
统计一个数字在排序数组中出现的次数。
例如输入排序数组[1, 2, 3, 3, 3, 3, 4, 5]和数字3,由于3在这个数组中出现了4次,因此输出4。
样例
输入:[1, 2, 3, 3, 3, 3, 4, 5] , 3
输出:4
class Solution(object):
def getNumberOfK(self, nums, k):
"""
:type nums: list[int]
:type k: int
:rtype: int
"""
if not nums:
return 0
l=0;r=len(nums)-1
while l<r:
mid=(l+r)//2
if nums[mid] <k:
l=mid+1
else:
r=mid
if nums[l] !=k:
return 0
left=l
l=0;r=len(nums)-1
while l<r:
mid=(l+r+1)//2
if nums[mid] <=k:
l=mid
else:
r=mid-1
return r-left+1
二分查找模板
两种划分模式:中点mid是属于左区间还是右区间的,如果nums[x]<k,则用第一种模板,因为mid属于左区间
如果nums[x]<=k,则用第二种模板,因为mid属于右区间
当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
二.需要加1的情况
当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
68. 0到n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0到n-1之内。
在范围0到n-1的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
样例
输入:[0,1,2,4]
输出:3
class Solution(object):
def getMissingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
l=0;r=len(nums)-1
while(l<r):
mid=l+r>>1
if nums[mid]==mid:
l=mid+1
else:
r=mid
if nums[r]==r:
r+=1
return r
判断划分条件是nums[mid] == mid,左边的均满足这个条件,右边的均不满足此条件,
注意的是当所有的nums[r]==r时,表示此时缺失的是n
69. 数组中数值和下标相等的元素
假设一个单调递增的数组里的每个元素都是整数并且是唯一的。
请编程实现一个函数找出数组中任意一个数值等于其下标的元素。
例如,在数组[-3, -1, 1, 3, 5]中,数字3和它的下标相等。
样例
输入:[-3, -1, 1, 3, 5]
输出:3
注意:如果不存在,则返回-1。
class Solution(object):
def getNumberSameAsIndex(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l=0;r=len(nums)-1
while l<r:
mid = l+r>>1
if nums[mid]<mid:
l=mid+1
else:
r=mid
if nums[r]==r:
return r
else:
return -1
70. 二叉搜索树的第k个结点
给定一棵二叉搜索树,请找出其中的第k小的结点。
你可以假设树和k都存在,并且1≤k≤树的总结点数。
样例
输入:root = [2, 1, 3, null, null, null, null] ,k = 3
2
/ \
1 3
输出:3
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def kthNode(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: TreeNode
"""
res=[]
self.flag =k
def middle_sort(root:TreeNode,k):
if not root:
return
middle_sort(root.left,k)
#res.append(root)
self.flag-=1
if not self.flag:
res.append(root)
return
middle_sort(root.right,k)
middle_sort(root,k)
return res[0]
要注意审题,题目中返回节点,所以在res.append()的时候要append(root)
71. 二叉树的深度
输入一棵二叉树的根结点,求该树的深度。
从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
样例
输入:二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
8
/ \
12 2
/ \
6 4
输出:3
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def treeDepth(self, root):
"""
:type root: TreeNode
:rtype: int
"""
if not root:
return 0
left = self.treeDepth(root.left)
right = self.treeDepth(root.right)
return max(left,right)+1
72. 平衡二叉树
输入一棵二叉树的根结点,判断该树是不是平衡二叉树。
如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
注意:
- 规定空树也是一棵平衡二叉树。
样例
输入:二叉树[5,7,11,null,null,12,9,null,null,null,null]如下所示,
5
/ \
7 11
/ \
12 9
输出:true
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
flag=True
def isBalanced(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
def dfs(root):
if not root:
return 0
left = dfs(root.left)
right = dfs(root.right)
if abs(left-right>1):
self.flag=False
return max(left,right)+1
dfs(root)
return self.flag
73. 数组中只出现一次的两个数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。
请写程序找出这两个只出现一次的数字。
你可以假设这两个数字一定存在。
样例
输入:[1,2,3,3,4,4]
输出:[1,2]
class Solution(object):
def findNumsAppearOnce(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
diff = 0
for i in nums:
diff ^=i
mask =1
while diff & mask ==0:
mask<<=1
num1=0;num2=0
for num in nums:
if num & mask==0: #注意是num与mask的与运算将所有数据分成两组
num1^=num
else:
num2^=num
return [num1,num2]
74. 数组中唯一只出现一次的数字
在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。
请找出那个只出现一次的数字。
你可以假设满足条件的数字一定存在。
思考题:
- 如果要求只使用 O(n)的时间和额外 O(1)的空间,该怎么做呢?
样例
输入:[1,1,1,2,2,2,3,4,4,4]
输出:3
class Solution(object):
def findNumberAppearingOnce(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
count = [0]*32
for num in nums:
k=0 #循环的时候每次k的值都要赋值为0
while k<32:
count[k]+= num>>k &1
k+=1
res =0
for i in range(32):
res += count[i] %3 * pow(2,i)
return res
75. 和为S的两个数字
输入一个数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。
如果有多对数字的和等于s,输出任意一对即可。
你可以认为每组输入中都至少含有一组满足条件的输出。
样例
输入:[1,2,3,4] , sum=7
输出:[3,4]
class Solution(object):
def findNumbersWithSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d={}
for num in nums:
if num in d.keys():
return [target-num,num]
else:
d[target-num] = num
76. 和为S的连续正数序列
输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。
例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、4~6和7~8。
样例
输入:15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]
class Solution(object):
def findContinuousSequence(self, sum):
"""
:type sum: int
:rtype: List[List[int]]
"""
s=0;j=1;res=[]
for i in range(1,sum//2+1):
while s<sum:
s+=j
j+=1
path=[]
if s==sum and i<j:
for k in range(i,j):
path.append(k)
res.append(path)
s-=i
return res
77. 翻转单词顺序
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
为简单起见,标点符号和普通字母一样处理。
例如输入字符串"I am a student."
,则输出"student. a am I"
。
样例
输入:"I am a student."
输出:"student. a am I"
class Solution(object):
def reverse(self,s):
start = 0
end = len(s)-1
while start<end:
s[start],s[end] = s[end],s[start]
start+=1
end-=1
def reverseWords(self, s):
"""
:type s: str
:rtype: str
"""
s= list(s.split(" "))
self.reverse(s)
return " ".join(s)
78. 左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。
请定义一个函数实现字符串左旋转操作的功能。
比如输入字符串"abcdefg"
和数字2,该函数将返回左旋转2位得到的结果"cdefgab"
。
注意:
- 数据保证n小于等于输入字符串的长度。
样例
输入:"abcdefg" , n=2
输出:"cdefgab"
class Solution(object):
def reverse (self,s,l,r):
r-=1 #要注意r-=1的情况,因为最大下标为r-1,会产生溢出
while l<r:
s[l],s[r] = s[r],s[l]
l+=1
r-=1
def leftRotateString(self, s, n):
"""
:type s: str
:type n: int
:rtype: str
"""
s=list(s)
self.reverse(s,0,len(s))
self.reverse(s,0,len(s)-n)
self.reverse(s,len(s)-n,len(s))
return "".join(s)
79. 滑动窗口的最大值
给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。
例如,如果输入数组[2, 3, 4, 2, 6, 2, 5, 1]及滑动窗口的大小3,那么一共存在6个滑动窗口,它们的最大值分别为[4, 4, 6, 6, 6, 5]。
注意:
- 数据保证k大于0,且k小于等于数组长度。
样例
输入:[2, 3, 4, 2, 6, 2, 5, 1] , k=3
输出: [4, 4, 6, 6, 6, 5]
from collections import deque
class Solution(object):
def maxInWindows(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
q = deque([])
res=[]
for i in range(len(nums)):
if i< k-1:
while q and q[-1]<nums[i]:
q.pop()
q.append(nums[i])
else:
while q and q[-1] <nums[i]:
q.pop()
q.append(nums[i])
res.append(q[0])
if nums[i-k+1] == q[0]:
q.popleft()
return res
80. 骰子的点数
将一个骰子投掷n次,获得的总点数为s,s的可能范围为n~6n。
掷出某一点数,可能有多种掷法,例如投掷2次,掷出3点,共有[1,2],[2,1]两种掷法。
请求出投掷n次,掷出n~6n点分别有多少种掷法。
样例1
输入:n=1
输出:[1, 1, 1, 1, 1, 1]
解释:投掷1次,可能出现的点数为1-6,共计6种。每种点数都只有1种掷法。所以输出[1, 1, 1, 1, 1, 1]。
样例2
输入:n=2
输出:[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
解释:投掷2次,可能出现的点数为2-12,共计11种。每种点数可能掷法数目分别为1,2,3,4,5,6,5,4,3,2,1。
所以输出[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]。
class Solution(object):
def numberOfDice(self, n):
"""
:type n: int
:rtype: List[int]
"""
dp = [[0]*(6*n+1) for _ in range(n+1)] #初始化---行为所有可能的和,列为投递的次数n
dp[0][0] = 1
res=[]
#dp[i][j]表示投递i次和为sum的总方案数
for i in range(1,n+1):
for j in range(1,(6*i)+1):
m=min(j,6)
for k in range(1,m+1):
dp[i][j] += dp[i-1][j-k]
for i in range(n,6*n+1):
res.append(dp[n][i])
return res
81. 扑克牌的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。
2~10为数字本身,A为1,J为11,Q为12,K为13,大小王可以看做任意数字。
为了方便,大小王均以0来表示,并且假设这副牌中大小王均有两张。
样例1
输入:[8,9,10,11,12]
输出:true
样例2
输入:[0,8,9,11,12]
输出:true
class Solution(object):
def isContinuous(self, numbers):
"""
:type numbers: List[int]
:rtype: bool
"""
if len(numbers)<5:
return False
numbers.sort()
cnt=0
for num in numbers:
if num==0:cnt+=1
for i in range(cnt,len(numbers)-1):
if numbers[i]==numbers[i+1]:
return False
cnt-=numbers[i+1]-numbers[i]-1
if cnt >=0:
return True
else:
return False
82. 圆圈中最后剩下的数字
0, 1, …, n-1这n个数字(n>0)排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。
求出这个圆圈里剩下的最后一个数字。
样例
输入:n=5 , m=3
输出:3
题意:让小朋友们围成一个大圈。然后,随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。
class Solution(object):
def lastRemaining(self, n, m):
"""
:type n: int
:type m: int
:rtype: int
"""
return 0 if n == 1 else (self.lastRemaining(n - 1, m) + m) % n
83. 股票的最大利润
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖 一次 该股票可能获得的利润是多少?
例如一只股票在某些时间节点的价格为[9, 11, 8, 5, 7, 12, 16, 14]。
如果我们能在价格为5的时候买入并在价格为16时卖出,则能收获最大的利润11。
样例
输入:[9, 11, 8, 5, 7, 12, 16, 14]
输出:11
class Solution(object):
def maxDiff(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res=0;minv=float("inf")
for num in nums:
minv = min(minv,num)
res = max(res,num-minv)
return res
84. 求1+2+…+n
求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
样例
输入:10
输出:55
import functools
class Solution(object):
def getSum(self, n):
"""
:type n: int
:rtype: int
"""
return functools.reduce(lambda x, y: x+y, range(n+1))
class Solution {
public:
int getSum(int n) {
int res = n;
//if(n>0) res=+getSum(n-1);
n>0 && (res += getSum(n-1)); //与运算起到if语句的作用
return res;
}
};
85. 不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、×、÷ 四则运算符号。
样例
输入:num1 = 1 , num2 = 2
输出:3
class Solution {
//异或又叫无进位加法 D=A^B 计算机里数电的基础实现
//进位 可以用与操作实现 C=A&B 多位数并行计算分成两步 先不考虑进位 再加上所有的进位 (A&B)<<1左移一位
public:
int add(int num1, int num2){
//假设num2末尾有k个0,num1&num2左移之后就会有k+1个0,因此最多循环32次,因为是32位数
while(num2) {
int sum = num1 ^ num2; //更新将得到的sum值与上一次的异或值继续做异或,直到进位为0
int carry =(num1 & num2) << 1;
num1 = sum;
num2 =carry;
}
return num1;
}
};
#python里面会爆栈,递归不能太多层
86. 构建乘积数组
给定一个数组A[0, 1, …, n-1]
,请构建一个数组B[0, 1, …, n-1]
,其中B中的元素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]
思考题:
- 能不能只使用常数空间?(除了输出的数组之外)
class Solution(object):
def multiply(self, A):
"""
:type A: List[int]
:rtype: List[int]
"""
if not A or len(A) == 0:
return []
tmp = 1
res = []
B = [0 for _ in range(len(A))]
B[0] = 1
for i in range(1, len(A)):
B[i] = B[i - 1] * A[i - 1]
# 得到的是A[0]乘到A[i - 1]
for j in range(len(A) - 2, -1, -1):
tmp *= A[j + 1]
B[j] *= tmp
# 乘上去的是A[n - 1]到A[i + 1]
return B