以牛客网题号为准
题目: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
思路: 利用二维数组的特点。采用二分的思想,从数组的左下角开始遍历。
# -*- coding:utf-8 -*-
class Solution:
# array 二维列表
def Find(self, target, array):
# write code here
if len(array) == 0 and len(array[0]) == 0:
return False
i=len(array)-1
j=0
while i >= 0 and j <= len(array[0])-1:
if target>array[i][j]:
j+=1
elif target<array[i][j]:
i-=1
else:
return True
return False
题目: 请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
思路: 把字符串中的每个字符一个个添加到新字符串中,如果遇到空格就把他换成%20。
class Solution:
def replaceSpace(self , s ):
# write code here
res=[]
for i in range(len(s)):
if s[i]==' ':
res.append('%20')
else:
res.append(s[i])
ss=''.join(res)
return ss
**题目:**输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。
思路:利用insert函数。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回从尾部到头部的列表值序列,例如[1,2,3]
def printListFromTailToHead(self, listNode):
# write code here
pTempt=listNode
res=[]
while pTempt:
res.insert(0,pTempt.val)
pTempt=pTempt.next
return res
题目: 给定某二叉树的前序遍历和中序遍历,请重建出该二叉树并返回它的头结点。
例如输入前序遍历序列{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):
# write code here
if len(pre)==0 or len(tin)==0:
return None
root=TreeNode(pre[0])
ind=tin.index(pre[0])
root.left=self.reConstructBinaryTree(pre[1:ind+1], tin[0:ind])
root.right=self.reConstructBinaryTree(pre[ind+1:len(pre)], tin[ind+1:len(tin)])
return root
题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路: 入栈时数据存入栈stackIn, 出栈时数据从stackOut弹出。执行入栈操作时,将数据源源不断的压入栈stackIn;执行出栈操作时,将stackIn的数据一次性全部弹出,存入到stackOut中。当stackOut栈非空时,不断弹出stackOut栈中的数据顺序即为队列的Pop顺序;当stackOut中的数据为空后,再将新入栈stackIn的数据一次性存入stackOut中即可。相比于上一种方式,这种方式极大降低了数据在栈stackIn和栈stackOut中来回无意义的腾挪操作,占据更低的存储空间,消耗更低的运算时间。
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
self.stackIn = []
self.stackOut = []
def push(self, node):
self.stackIn.append(node)
def pop(self):
if self.stackOut:
return self.stackOut.pop()
elif not self.stackIn:
return None
else:
while self.stackIn:
self.stackOut.append(self.stackIn.pop())
return self.stackOut.pop()
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
# -*- coding:utf-8 -*-
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if len(rotateArray)==0:
return 0
left=0
right=len(rotateArray)-1
while left<right:
mid=(left+right)//2
if rotateArray[mid]>rotateArray[right]:
left=mid+1
elif rotateArray[mid]<rotateArray[right]:
right=mid
else:
right-=1
return rotateArray[left]
题目: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
思路: 递归法时间复杂度过高。因此采用递推法,时间复杂度为O(n)。
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
a,b=0,1
for i in range(n):
a,b=b,a+b
return a
递归
def numWays(self, n: int) -> int:
if n == 0:
return 1
elif n == 1:
return 1
elif n == 2:
return 2
else:
return (self.numWays(n - 1) + self.numWays(n-2))
非递归:
class Solution:
def jumpFloor(self, number):
# write code here
if number<1:
return 0
a=1
b=2
for i in range(number-1):
a,b=b,a+b
return a
**题目:**一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶(n为正整数)总共有多少种跳法。
思路:
f [ n ] = f [ n − 1 ] + f [ n − 2 ] + . . . + f [ 0 ] f[n] = f[n-1] + f[n-2] + ... + f[0] f[n]=f[n−1]+f[n−2]+...+f[0]
f [ n − 1 ] = f [ n − 2 ] + f [ n − 3 ] + . . . + f [ 0 ] f[n-1] = f[n-2] + f[n-3] + ... + f[0] f[n−1]=f[n−2]+f[n−3]+...+f[0]
所以一合并, f [ n ] = 2 ∗ f [ n − 1 ] = 2 n − 1 f[n] = 2*f[n-1]=2^{n-1} f[n]=2∗f[n−1]=2n−1,初始条件f[0] = f[1] = 1
# -*- coding:utf-8 -*-
class Solution:
def jumpFloorII(self, number):
# write code here
return pow(2,number-1)
题目: 我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2n的大矩形,总共有多少种方法?
比如n=3时,23的矩形块有3种覆盖方法:
思路: 假设2*n的第一个矩形竖着放,则剩下的就是f(n-1).假设第一个横着放,那么第二个必须在下面横着放,剩下的就是f(n-2)
则递推公式为f(n)=f(n-1)+f(n-2),且f(1)=1,f(2)=2.
(注意n<=1的情况)
class Solution:
def rectCover(self, number):
# write code here
if number<=1:
return number
a=1
b=2
for i in range(number-1):
a,b=b,a+b
return a
题目: 输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
思路: 1100&1011=1000。也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。
但python当超出int的32位时会自动转化为long型,上述代码“n = n &(n - 1)”在执行时,当执行到倒数第二步,即原来的整数变成 1(31个0)时,该整数减一,在c++中结果为0(31个1),相与之后结果为0,终止循环。但是python在计算该整数减一时,会得到1(32个0),陷入无限循环。因此通过“n & 0xffffffff”实现python只取32位的功能,相与之后32位之前不会再有值。
class Solution:
def NumberOf1(self, n):
# write code here
cou = 0
if n < 0:
n = n & 0xffffffff
while n:
cou = cou + 1
n = n &(n - 1)
return cou
题目: 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
思路: 如果base为0,直接返回0。如果exponent为0,返回1.
采用递推公式,如果exponent为正数:Power(base, exponent)=base*Power(base, exponent-1)。
如果exponent为负数:Power(base, exponent)=(1/base)*Power(base, exponent+1)
class Solution:
def Power(self, base, exponent):
# write code here
if base==0:
return 0
if exponent==0:
return 1
if exponent>0:
return base*self.Power(base, exponent-1)
else:
return (1/base)*self.Power(base, exponent+1)
# -*- coding:utf-8 -*-
class Solution:
def Power(self, base, exponent):
# write code here
if base==0:
return 0
if exponent>0:
if exponent%2==0:
result=self.Power(base, exponent//2)
result=result**2
return result
elif exponent%2==1:
result=self.Power(base, exponent//2)**2
result=result*base
return result
elif exponent<0:
result=self.Power(1/base, abs(exponent))
return result
else:
return 1
**题目:**输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路: 遍历,若余数为1,append到奇数数组,反之append到偶数数组。最后讲奇数和偶数数组加起来即可。
class Solution:
def reOrderArray(self , array ):
# write code here
oddarray=[]
evenarray=[]
for i in array:
if i%2==0:
evenarray.append(i)
else:
oddarray.append(i)
return oddarray+evenarray
题目: 输入一个链表,输出该链表中倒数第k个结点。
思路: 在链表中:倒数的+顺数的长度等于链表总长度,所以可以设置两个指针,一个先走K步,剩下的到链表的末尾要走的步数就是倒数第k个节点需要从头开始走的步数。
注意在先移动k步快指针时,需要先判断k是否为空再挪指针,因为当快指针第一次为空时,慢指针不是None。否则,若第k步正好快指针指向None时慢指针也会返回None,是不对的。
class Solution:
def FindKthToTail(self , pHead , k ):
# write code here
fast=pHead
slow=pHead
for i in range(k):
if not fast:
return None
fast=fast.next
while fast:
fast=fast.next
slow=slow.next
return slow
题目: 输入一个链表,反转链表后,输出新链表的表头。
思路: 先保留现有链表的第二个节点,将现有链表的头指向已反转的链表。从现有链表第二个节点开始为新的链表,更新已反转的链表。迭代至尾结点。
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
if pHead==None:
return None
last=None
while pHead:
tmp=pHead.next
pHead.next=last
last=pHead
pHead=tmp
return last
题目: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路: 利用递归,首先如果有一个链表为空,则直接返回另一个链表。比较两个链表的值,将表头小的链表指向下一个,并递归调用。
class Solution: