892 三维形体的表面积
输入[[2]],输出[10]。输入[[1,2],[3,4]],输出4上+4下+前7+后7+左6+右6=34。所以思路就是计算上、前、左,然后乘2。但其实不是这样的,这样会漏掉[[1,1,1],[1,0,1],[1,1,1]]中间凹下去的四周的表面积。但如果计算和四周的高度,则会错过[2,0,4]这样应该是漏掉4个但是加了6的情况。所以看答案思路:考虑每个位置贡献的表面积。这个贡献就是,如果比周围的高就有贡献,那么就不用考虑低的情况了。自己写的代码非常不简洁 不管了 做累了 不优化了。
class Solution(object):
def surfaceArea(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
# # 没考虑到中间空下去的4个啊
# row, colomn = len(grid), len(grid[0])
# res = 0
# for i in range(row):
# res += max(x for x in grid[i])
# for j in range(colomn):
# tmp = []
# for k in range(row):
# tmp.append(grid[k][j])
# res += max(tmp)
# res += sum(grid[i][j]!=0 for i in range(row) for j in range(colomn))
# res = res * 2
# # 考虑凹陷情况考虑不全,没有考虑到[2,0,4]需要增加的是4不是6
# new = [[0]*(colomn+2) for _ in range(row+2)]
# for i in range(row):
# for j in range(colomn):
# new[i+1][j+1] = grid[i][j]
# for i in range(1,row+1):
# for j in range(1,colomn+1):
# a = new[i-1][j-1] - new[i][j]
# b = new[i-1][j+1] - new[i][j]
# c = new[i+1][j-1] - new[i][j]
# d = new[i+1][j+1] - new[i][j]
# if a>=0 and b>=0 and c>=0 and d>=0 and (a*b>0 or c*d>0):
# res += (a+b+c+d)
# return res
row, colomn = len(grid), len(grid[0])
new = [[0]*(row+2) for _ in range(colomn+2)]
for i in range(row):
for j in range(colomn):
new[i+1][j+1] = grid[i][j]
sum = 0
for i in range(row):
for j in range(colomn):
cur = new[i+1][j+1]
left = new[i+1][j]
right = new[i+1][j+2]
up = new[i][j+1]
down = new[i+2][j+1]
if cur>0:
sum += 2
sum += max(cur-left,0)
sum += max(cur-right,0)
sum += max(cur-up,0)
sum += max(cur-down,0)
return sum
537 复数乘法
复数的乘法,a=“1+1i”, b=“1+1i”, res=1+i^2+2i=0+2i,输出以“0+2i”输出。因为是数学只要会做用python写出计算机语言即可,虽然自己写的比较麻烦,但是好理解(比如根本不用判断i,最后一位就是i)。字符串相加用+,数组引用a[A:B]包含A不包含B,都挺基本的。
class Solution(object):
def complexNumberMultiply(self, a, b):
"""
:type a: str
:type b: str
:rtype: str
"""
for i in range(len(a)):
if a[i] == '+':
num1 = i
A = int(a[:num1])
if a[i] == 'i':
B = int(a[num1+1:i])
for i in range(len(b)):
if b[i] == '+':
num2 = i
C = int(b[:num2])
if b[i] == 'i':
D = int(b[num2+1:i])
res = str(A*C-B*D)+'+'+str(A*D+B*C)+'i'
return res
1447最简分数
最简分数就是输入n=3,返回[“1/2”,“1/3”,“2/3”],输入n=4,返回[“1/2”,“1/3”,“1/4”,“2/3”,“3/4”]。
class Solution(object):
def common(self,i,j):
flag = 1
for k in range(2, min(i,j)):
if i%k ==0 and j%k == 0:
flag = 0
return True if flag else False
def simplifiedFractions(self, n):
"""
:type n: int
:rtype: List[str]
"""
res = []
if n == 1:
return res
if n == 2:
res = ["1/2"]
return res
for i in range(2,n+1):
for j in range(1,i):
if (i % j != 0 or j == 1) and self.common(i,j):
res.append(str(j)+'/'+str(i))
return res
877 石子游戏
这道题目战略性放弃,这道题目告诉我们,没时间的话,直接蒙return true 就能ac。
题目就是,两个人从偶数长度的list中选择前面or后面的石子,和大者获胜。由于如此取,只能最后取到全是idx为偶的或者all even。因此,先手可以计算两个和,选择偶数(第一个拿头上的)或者奇数(第一个拿最后的)。因此总能赢。
60 第k个排列
输入n=4,k=9,返回1234的全排列的第9大的数字。刚开始以为列出全排列数组,然后取第9个,列的时候发现可以根据k和n的数学关系决定输出每个位置的value。找规律的题目数学还是会做的,写成代码就很艰难了,还是业务能力不熟练啊。
class Solution(object):
def jiecheng(self,x):
multi = 1
for i in range(1,x+1):
multi *= i
return multi
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
if n==1:
return str(1)
a = []
for i in range(1,n+1):
a.append(i)
idx = []
for i in range(n-1,1,-1):
yushu = k // self.jiecheng(i)
if k % self.jiecheng(i) != 0:
idx.append(a[yushu])
a.remove(a[yushu])
else:
idx.append(a[yushu-1])
a.remove(a[yushu-1])
k = k % self.jiecheng(i)
if k == 1:
idx.append(a[0])
a.remove(a[0])
idx.append(a[0])
else:
idx.append(a[1])
a.remove(a[1])
idx.append(a[0])
res = 1
for i in range(n):
res += idx[i]*(10**(n-i-1))
return str(res-1)
2 两数相加
ListNode形式还是逆序保存,: 7 -> 0 -> 8 存的是807。给出了单链定义,引用当前位置节点x使用.val,引用下一个节点使用.next。使用递归的方法会简单一些,就是自己定义一个函数循环调用所以不需要写self,循环的时候还需要一个进位变量,当三个都为0的时候return None结束,不然的话就是当前位为三者和的个位,进位为十位。python取整直接//,和int( / )等价。注意当前节点保存的时候以ListNode形式保存。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
def calcu(s1, s2, jinwei):
if not s1 and not s2 and not jinwei: return None
res = (s1.val if s1 else 0) + (s2.val if s2 else 0) + jinwei
node = ListNode(res % 10)
node.next = calcu(s1.next if s1 else None, s2.next if s2 else None, res // 10)
return node
return calcu(l1, l2, 0)
233 数字1 的个数
纯数学题,找规律,实现方法不固定。假设342: 分成3和42进行递归。3贡献了100-199的100个,这个100是因为3在百,然后还有0-99,100-199,200-299的三倍的考虑0-99的1,以及300+的300-342出现的1。所以power=100,def(99),def(42)。如果是142:分成1和42处理,高位1只贡献了100-142共43个1,也没贡献倍数的def(99),后面的42贡献了循环计算def(42),所以last+1=42+1,def(99),低位贡献def(42)。
class Solution(object):
def countDigitOne(self, n):
"""
:type n: int
:rtype: int
"""
if n <= 0: return 0
if n < 10: return 1
high = int(str(n)[0])
last = int(str(n)[1:])
power = 10**(len(str(n))-1)
if high == 1:
return (last+1) + self.countDigitOne(power-1) + self.countDigitOne(last)
else:
return power + high * self.countDigitOne(power-1) + self.countDigitOne(last)