2019/4/9,目前一共66道,我也是小白,定个目标半个月完成,让我们一起开始吧!
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
思路:
就是用python写这个常用数列啦!
解法:
class Solution:
def Fibonacci(self, n):
# write code here
F = [0,1,1]
if n < 3:
return F[n]
for i in range(3,n+1):
num = F[i-1]+F[i-2]
F.append(num)
return F[n]
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
思路:
斐波那契数列的应用。对于本题,前提只有 一次 1阶或者2阶的跳法。
a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
e.可以发现最终得出的是一个斐波那契数列:
f ( n ) = { 1 , n = 1 2 , n = 2 f ( n − 1 ) + f ( n − 2 ) , n > 2 f(n)= \left\{\begin{matrix} 1,n=1\\ 2,n=2\\ f(n-1)+f(n-2) ,n>2 \end{matrix}\right. f(n)=⎩⎨⎧1,n=12,n=2f(n−1)+f(n−2),n>2
解法:
# -*- coding:utf-8 -*-
class Solution:
def jumpFloor(self, n):
# write code here
res=[1,2,3] #台阶从1开始,到n
while len(res)<= (n-1): #列表计数从0开始,则n-1结束
res.append(res[-1]+res[-2])
return res[n-1] #n-1对应实际的最后一个台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:
在上一题上的变种,但不是斐波那契数列的应用,更像是找规律。(链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387)
关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
f(1) = 1
f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
f(3) = f(3-1) + f(3-2) + f(3-3)
…
f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)
说明:
1)这里的f(n) 代表的是n个台阶有一次1,2,…n阶的 跳法数。
2)n = 1时,只有1种跳法,f(1) = 1
3 ) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2)
4 ) n = 3时,会有三种跳得方式,1阶、2阶、3阶,那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)。因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
5 ) n = n时,会有n中跳的方式,1阶、2阶…n阶,得出结论:
f(n) = f(n-1)+f(n-2)+…+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + … + f(n-1)
6 ) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
f(n-1) = f(0) + f(1)+f(2)+f(3) + … + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + … + f(n-2)
f(n) = f(0) + f(1) + f(2) + f(3) + … + f(n-2) + f(n-1) = f(n-1) + f(n-1)
可以得出:
f(n) = 2*f(n-1)
7 ) 得出最终结论,在n阶台阶,一次有1、2、…n阶的跳的方式时,总得跳法为:
f ( n ) = { 1 , n = 0 1 , n = 1 2 ∗ f ( n − 1 ) , n > = 2 f(n)= \left\{\begin{matrix} 1,n=0\\ 1,n=1\\ 2*f(n-1) ,n>=2 \end{matrix}\right. f(n)=⎩⎨⎧1,n=01,n=12∗f(n−1),n>=2
解法:
# -*- coding:utf-8 -*-
class Solution:
def jumpFloorII(self,number):
# write code here
if(number < 3):
return number
else:
return 2**(number - 1)
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
# -*- coding:utf-8 -*-
class Solution:
def rectCover(self, number):
# write code here
f=[0,1,2]
for i in range(3,number+1):
num=f[i-1] + f[i-2]
f.append(num)
return f[number]
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:
解法:
在这里插入代码片
在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路:
解法:
在这里插入代码片
给定一个数组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]。不能使用除法。
B[i]的值可以看作下图的矩阵中每行的乘积。下三角用连乘可以很容求得,上三角,从下向上也是连乘。因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
# -*- coding:utf-8 -*-
class Solution:
def multiply(self,A):
# write code here
size_A=len(A)
b=[1]
if size_A == 0 or size_A ==1:
return A
for i in range(1,size_A):
num = A[i-1] * b[i-1]
b.append(num)
temp = 1
for j in range(size_A-1,0,-1):
b[j] = temp*b[j]
temp = temp*A[j]
b[0] = temp*b[0]
return b
请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。
思路:
来源:https://www.nowcoder.com/questionTerminal/45327ae22b7b413ea21df13ee7d6429c
解这题需要把题意仔细研究清楚,反正我试了好多次才明白的。
首先,考虑特殊情况:
1>两个字符串都为空,返回true
2>当第一个字符串不空,而第二个字符串空了,返回false(因为这样,就无法匹配成功了,而如果第一个字符串空了,第二个字符串非空,还是可能匹配成功的,比如第二个字符串是“aaaa”,由于 “ * ” 之前的元素可以出现0次,所以有可能匹配成功)之后就开始匹配第一个字符,这里有两种可能:匹配成功或匹配失败。但考虑到pattern下一个字符可能是 “ * ”, 这里我们分两种情况讨论:pattern下一个字符为“ * ” 或不为“ * ” :
1>pattern下一个字符不为“ * ” :这种情况比较简单,直接匹配当前字符。如果匹配成功,继续匹配下一个;如果匹配失败,直接返回false。注意这里的 “匹配成功”,除了两个字符相同的情况外,还有一种情况,就是pattern的当前字符为‘‘ . ’,同时str的当前字符不为 ‘\0’。
2>pattern下一个字符为“ * ” 时,稍微复杂一些,因为“ * ” 可以代表0个或多个。这里把这些情况都考虑到:
a>当“ * ” 匹配0个字符时,str当前字符不变,pattern当前字符后移两位,跳过这个“ * ” 符号;
b>当“ * ” 匹配1个或多个时,str当前字符移向下一个,pattern当前字符不变。(这里匹配1个或多个可以看成一种情况,因为:当匹配一个时,由于str移到了下一个字符,而pattern字符不变,就回到了上边的情况a;当匹配多于一个字符时,相当于从str的下一个字符继续开始匹配)之后再写代码就很简单了。
解法:
# -*- coding:utf-8 -*-
class Solution:
# s, pattern都是字符串
def match( self,s, pattern):
if len(s)==0 and len(pattern)==0:
return True
if len(s)>0 and len(pattern)==0:
return False
if len(pattern)==1 and len(s)==0 and ( pattern[0]!='.'):
return False
if len(pattern)>1:
if pattern[1]!='*':
if len(s)>0 and (s[0]==pattern[0] or pattern[0]=='.'):
return self.match(s[1:],pattern[1:])
else:
return False
if pattern[1]=='*':
print(len(s))
if len(s)>0 and (s[0]==pattern[0] or pattern[0]=='.'):
return self.match(s[1:],pattern) or self.match(s[1:],pattern[2:]) or self.match(s,pattern[2:])
else:
return self.match(s,pattern[2:])
if (pattern[0]=='.' or s[0]==pattern[0]) and len(s)>0:
return self.match(s[1:],pattern[1:])
return False
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。
思路:
列举所有可能的情况,傻瓜式解决,如果有更好的多多交流啊!
解法:
# -*- coding:utf-8 -*-
class Solution:
# s字符串
def isNumeric(self, s):
if len(s)==0:
return False
new_s=''
count=0
s_dict='0123456789'
if s[0]=='+' or s[0]=='-':
s=s[1:]
i=0
ret=True
while i <len(s) and ret:
if s[i] in s_dict:
new_s +=s[i]
elif s[i]=='.':
count +=1
elif s[i]=='+' or i=='-':
ret= False
elif s[i]=='e' or s[i]=='E':
if i==len(s)-1:
ret=False
break
if (s[i+1] in s_dict) or (s[i+1]=='+')or s[i+1]=='-':
ret= True
if s[i+1]=='+' or s[i+1]=='-':
i += 1
if '.' in s[i:]:
ret = False
else:
ret=False
i += 1
if count>1:
ret= False
return ret
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here应该用二分查找
if rotateArray == []:
return 0
low=rotateArray[-1]
for i in range(len(rotateArray)-2,0,-1):
if rotateArray[i] <= low:
low = rotateArray[i]
else:
return low
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
思路:
递归
解法:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
if pre==[]:
return None
root=TreeNode(pre[0])
root.left=self.reConstructBinaryTree(pre[1:tin.index(pre[0])+1],tin[:tin.index(pre[0])])
root.right=self.reConstructBinaryTree(pre[tin.index(pre[0])+1:],tin[tin.index(pre[0])+1:])
return root
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
递归的终止条件是我们达到了树A或者树B的叶节点。有地方要重点注意,DoesTree1haveTree2()函数中的两个 if 判断语句 不能颠倒顺序 。因为如果颠倒了顺序,会先判断pRoot1 是否为None, 其实这个时候,pRoot1 的节点已经遍历完成确认相等了,但是这个时候会返回 False,判断错误。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def HasSubtree(self, pRoot1, pRoot2):
if pRoot1 !=None and pRoot2 !=None:
if pRoot1.val==pRoot2.val:
l1=self.issubtree(pRoot1,pRoot2)
l2=self.issubtree(pRoot1.left,pRoot2)
l3=self.issubtree(pRoot1.right,pRoot2)
return l1 or l2 or l3
else:
return False
def issubtree(self,pre,tin):
if tin==None: #pRoot2遍历到叶子结点
return True
if pre==None and tin!=None:
return False
if pre.val!= tin.val:
return False
return self.issubtree(pre.left,tin.left) and self.issubtree(pre.right,tin.right)
操作给定的二叉树,将其变换为源二叉树的镜像。
思路:
遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子节点,当交换完所有的非叶子结点的左右子结点之后,就得到了树的镜像。
解法:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回镜像树的根节点
def Mirror(self, root):
# 先考虑空的情况
if root == None:
return None
else:
root.left,root.right = root.right,root.left
self.Mirror(root.left)
self.Mirror(root.right)
return root
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
思路:
首先根节点以及其左右子树非空,左子树的左子树和右子树的右子树相同,左子树的右子树和右子树的左子树相同即可,采用递归非递归都可,采用栈或队列存取各级子树根节点。
解法:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isSymmetrical(self, pRoot):
if pRoot==None:
return True
return self.compare(pRoot.left,pRoot.right)
def compare(self,ptree,qtree):
if ptree==None and qtree==None:
return True
if ptree==None or qtree==None:
return False
if ptree.val==qtree.val:
if self.compare(ptree.left,qtree.right) and self.compare(ptree.right,qtree.left):
return True
else:
return False
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路:
二叉树的广度优先遍历
解法:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回从上到下每个节点值列表,例:[1,2,3]
def PrintFromTopToBottom(self, root):
if root == None:#没有的话直接返回
return []
d=[]
ret=[]
d.append(root)
print(d)
while d:
root=d.pop(0)
if root.left != None:
d.append(root.left)
if root.right != None:
d.append(root.right)
ret.append(root.val)
return ret
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
思路:
每次循环都要用两个数组,浪费了空间
思路:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二维列表[[1,2],[4,5]]
def Print(self, pRoot): #指向左右子树
if pRoot == None:#没有的话直接返回
return []
d=[pRoot] #每一次的每一行节点
result=[]
while d:
new_d=[]
new_res=[]
for i in d:
new_res.append(i.val)
if i.left!=None:
new_d.append(i.left)
if i.right!=None:
new_d.append(i.right)
result.append(new_res)
d=new_d
return result
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:
在上一个题目把二叉树打印成多行的基础上,增加了判断:如果列表索引为偶数,列表顺序不变;如果列表索引为奇数,列表[::-1]。加入到新的result中输出。
解法:
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def Print(self, pRoot):
if pRoot == None:#没有的话直接返回
return []
d=[pRoot] #树的根
result=[]
while d:
new_d=[]
new_res=[]
for i in d:
new_res.append(i.val)
if i.left!=None:
new_d.append(i.left)
if i.right!=None:
new_d.append(i.right)
result.append(new_res)
d=new_d
new_result=[]
for i, element in enumerate(result):
if i%2==0:
new_result.append(element)
else:
new_result.append(element[::-1])
return new_result
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
# -*- coding:utf-8 -*-
# class TreeLinkNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
# self.next = None
class Solution:
def GetNext(self, pNode):
if pNode==None:
return
#if pNode.next==None:
# return None
if pNode.right:
p=pNode.right
while p.left:
p=p.left
return p
while pNode.next:
if pNode.next.left==pNode:
return pNode.next
pNode=pNode.next
else:
return None
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
# -*- coding:utf-8 -*-
class Solution:
def VerifySquenceOfBST(self, sequence):
if sequence == None or len(sequence)==0:
return False
#root = sequence[len(sequence)-1] #根
root = sequence[-1]
lens = len(sequence)
for i in range(lens):
if sequence[i] > root:
break
#left = sequence[:i]
for j in range(i,lens):
if sequence[j] < root:
return False
#right = sequence[i:(lens-1)]
#判断左右子树
boolleft = True
if i > 0:
boolleft = self.VerifySquenceOfBST(sequence[:i])
boolright = True
if i < (lens-1):
boolright = self.VerifySquenceOfBST(sequence[i:-1])
return boolleft and boolright
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
# 返回二维列表,内部每个列表表示找到的路径
def __init__(self):#如果不定义在外部,递归调用左右子树就会改变path和sumpath
self.sumpath = []
self.path = []
def FindPath(self, root, expectNumber):
# write code here
#递归先序遍历树, 把结点加入路径。
#若该结点是叶子结点则比较当前路径和是否等于期待和。
#弹出结点,每一轮递归返回到父结点时,当前路径也应该回退一个结点
if root == None:
return self.sumpath
#不为空的情况
self.path.append(root.val)
expectNumber -= root.val
if expectNumber == 0 and root.left == None and root.right == None:
templist = []
for _ in self.path:
templist.append(_)
self.sumpath.append(templist)
self.FindPath(root.left,expectNumber)
self.FindPath(root.right,expectNumber)
self.path.pop()
return self.sumpath
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
思路:
链表值倒序即可。
解法:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
newlist=[]
while listNode:
newlist.append(listNode.val)
listNode=listNode.next
return newlist[::-1]
输入一个链表,输出该链表中倒数第k个结点。
思路:
跟上面一题思路一样,只不过是倒数第k个。
解法:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
result=[]
if head==None:
return
while head!=None:
result.append(head)
head=head.next
if k>len(result) or k==0:
return None
return result[-k]
输入一个链表,反转链表后,输出新链表的表头。
思路:
easy题,要注意表头不仅有值,还有指向下一个节点的指针。
解法:
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
if pHead == None or pHead.next == None:
return pHead
last = None
while pHead: #{1,2,3,4,5}
fore = pHead.next #fore现在为2的地址
pHead.next = last #1指向了None
last = pHead #1和它的指针赋给last
pHead = fore #2为首的链表赋给pHead
return last
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。
思路:
每k个节点进行一次反转,用两个指针记录k个区间的首尾节点,写一个reverse函数反转该局部内的节点指向,接着继续向后走,不停的取k个进行反转,如果不够k个就返回。。
解法:
def reverse(array, left, right, k):
cishu = k // 2
while cishu > 0:
array[left], array[right] = array[right], array[left]
left += 1
right -= 1
cishu -= 1
array = list(map(int, input().split()))
k = int(input())
beishu = len(array) // k
left = 0
right = k-1
for i in range(beishu):
reverse(array, left, right, k)
left += k
right += k
print(" ".join(str(i) for i in array))
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
#普通解法
temp=ListNode(0) #初始化一个节点
result=temp #这里的时候result和temp是一样的
while pHead1 and pHead2: #这里只能是and而不是or
if pHead1.val <= pHead2.val:
temp.next = pHead1
pHead1 = pHead1.next
else:
temp.next = pHead2
pHead2 = pHead2.next
temp=temp.next
if pHead1 == None: #如果链表1结束,接链表2
temp.next = pHead2
if pHead2 == None: #如果链表2结束,接链表1
temp.next = pHead1
return result.next #因为temp的头节点值为0
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回合并后列表
def Merge(self, pHead1, pHead2):
#递归解法
if pHead1 == None:
return pHead2
if pHead2 == None:
return pHead1
while pHead1 and pHead2:
if pHead1.val <= pHead2.val:
pHead1.next = self.Merge(pHead1.next, pHead2)
return pHead1
else:
pHead2.next = self.Merge(pHead1, pHead2.next)
return pHead2
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。
# -*- coding:utf-8 -*-
# class RandomListNode:
# def __init__(self, x):
# self.label = x
# self.next = None
# self.random = None
class Solution:
# 返回 RandomListNode
def Clone(self, pHead):
# write code here
if not pHead: #空链表返回none
return None
temp = pHead #为了重新让dummy指向表头,为了下一步从表头开始操作准备
#第一步:复制N'
while temp: #复制了一个复杂链表的副本
tempnext = temp.next
copynode = RandomListNode(temp.label)
copynode.next = tempnext
temp.next = copynode
temp = tempnext
#第二步:random指向random
temp = pHead
while temp:
temprandom = temp.random
copynode = temp.next
if temprandom:
copynode.random=temprandom.next
temp = copynode.next
#第三步:两部分分离
temp = pHead
copyHead = pHead.next#第二个节点开始为复制后的
while temp:
copynode = temp.next
tempnext = copynode.next
temp.next = tempnext
if tempnext:
copynode.next = tempnext.next
else:
copynode.next = None
temp = tempnext#每次操作都是从原N开始
return copyHead
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
count=0
if n==0:
return 0
if n<0:
n=n&0XFFFFFFFF
return bin(n).count('1')
while (n!=0):
count=count+1
n=(n-1)&n
return count
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
#return base**(exponent) #但是没用到算法思想
#第二种思想:分情况讨论
result=1
if base==0:
return 0
if exponent==0:
return 1
if exponent>0:
for _ in range(exponent):
result=result*base
return result
if exponent<0:
for _ in range(abs(exponent)):
result=result*base
return 1/result
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
# -*- coding:utf-8 -*-
class Solution:
def reOrderArray(self, array):
single=[] #存放奇数
double=[] #存放偶数
for i in array:
if i%2==1:
single.append(i)
else:
double.append(i)
return single+double
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
a = [1,2,3]
b = [4,5,6]
zipped = zip(a,b) # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)] #output
# -*- coding:utf-8 -*-
#链接:https://www.nowcoder.com/questionTerminal/9b4c81a02cd34f76be2659fa0d54342a
#来源:牛客网
#打印第一行,删除第一行,逆时针转动90度。重复以上步骤,直到矩阵为空。
class Solution:
def printMatrix(self, matrix):
# write code here
s=[]
while matrix:
s+=matrix[0]
del matrix[0]
matrix=zip(*matrix)[::-1]
return s
我的大众解法:
分为两个步骤:
# -*- coding:utf-8 -*-
class Solution:
# matrix类型为二维列表,需要返回列表
def printMatrix(self, matrix):
# Q1:如何求矩阵的维数
result=[] #存储结果
rows = len(matrix) #行数
columns = len(matrix[0]) #列数
start = 0
while (rows>start*2) and (columns>start*2):#保证可以循环的条件
end_y = columns-1-start #本次循环结束列
end_x = rows-1-start #本次循环结束行
#从左到右打印一行
for i in range(start,end_y+1): #还是要把起点终点写上,因为动态变化
result.append(matrix[start][i])
#从上到下打印一列
if start < end_x:
for j in range(start+1,end_x+1):
result.append(matrix[j][end_y])
#从右到左
if start < end_y and start < end_x:
for m in range(end_y-1,start-1,-1):
result.append(matrix[end_x][m])
#从下到上打印
if (start+1)<end_x and start<end_y:
for n in range(end_x-1,start,-1):
result.append(matrix[n][start])
start=start+1
return result
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))
思路:
链接:https://www.nowcoder.com/questionTerminal/4c776177d2c04c2494f2555c9fcc1e49
来源:牛客网
我们可以设计两个栈:一个就是普通的栈,另外一个存储push进来的最小值。
Note:不能用python自带的min函数,因为时间复杂度应为O(n)
解法:
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stack=[] #定义一个空列表为进行操作的栈
self.stack_min=[] #存放小值
def push(self, node):
if not self.stack_min:#判断是否为空
self.stack_min.append(node)#如果为空直接append
else: #不为空
if node < self.stack[-1]:#比较node和栈顶元素
self.stack_min.append(node)#node小就把node直接append
else:
self.stack_min.append(self.stack_min[-1])#为了保证长度一致append之前的栈顶最小元素
self.stack.append(node)#这一步是stack必须做的
def pop(self):
if self.stack:
self.stack_min.pop()#要注意pop会直接返回列表删除元素
return self.stack.pop()
def top(self):#这个函数貌似没用
if self.stack:
return self.stack[-1]
def min(self):
if self.stack_min:
return self.stack_min[-1]
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# write code here
stack = []#辅助栈
for psh in pushV: #遍历入栈[1,2,3,4,5
stack.append(psh)
if stack[-1] == popV[0]:#相等都删除
popV.pop(0)
stack.pop()
for pp in popV:#此时popV剩下[3,2,1]
if pp == stack[-1]:
stack.pop()
return stack == []
https://blog.csdn.net/tinkle181129/article/details/79326023
https://www.cnblogs.com/yanmk/p/9130681.html
来源:牛客网 ↩︎
来源:牛客网 ↩︎