题目描述1
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
# -*- JluTiger -*-
class Solution:
# array 二维列表
def Find(self, target, array):
rows=len(array)
cols=len(array[0])
if rows>0 and cols>0:
row=0
col=cols-1
while col>=0 and row<rows:
if target==array[row][col]:
return True
elif target<array[row][col]:
col-=1
else:
row+=1
return False
题目描述 2请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are
Happy.则经过替换之后的字符串为We%20Are%20Happy。
方法1:直接使用replace函数
方法2:
# -*- coding:utf-8 -*-
class Solution:
# s 源字符串
def replaceSpace(self, s):
return s.replace(' ','%20')
class Solution:
# s 源字符串
def replaceSpace(self, s):
return "%20".join(list(s.split(" ")))
# write code here
. join(): 连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串
# -*- coding:utf-8 -*-
class Solution:
# s 源字符串
def replaceSpace(self, s):
# write code here
new_s = ''
for j in s:
if j == ' ':
new_s=new_s + '%20'
else:
new_s=new_s + j
return new_s
3–旋转数组的最小元素
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路1:对于数组中的元素,两两比较
思路2:二分查找法
思路3–sort排序
思路4–直接min函数
方法1--两两比较
class Solution:
def minNumberInRotateArray(self, array):
if len(array)==0:
return 0
i=0
for i in range(len(array)):
if (array[i]>array[i+1]):
return array[i+1]
return array[0]
# write code here
class Solution:
def minNumberInRotateArray(self, array):
if len(array) ==0:
return 0
left=0
right = len(array)-1
mid=-1
while(array[left]>array[right]):
if(right-left==1):
mid=right
break
mid=left+(right-left)/2
if(array[mid]>=array[left]):
left=mid
if (array[mid]<array[right]):
right=mid
return array[mid]
循环太大
方法3:先sort排序
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
else:
rotateArray.sort()
return rotateArray[0]
方法4-min函数
class Solution:
def minNumberInRotateArray(self, rotateArray):
# write code here
if not rotateArray:
return 0
else:
return min(rotateArray)
题目5
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
思路1:非递归实现—直接按照数列数学公式计算-满足时间复杂度 先把n = 0,1,2,这三个项确定了再使用递归斐波那契数列数列从第3项开始,每一项都等于前两项之和数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 23。。。
方法1--非递归
class Solution:
def Fibonacci(self, n):
if n == 0:
return 0
if n == 1:
return 1
if n == 2:
return 1
if n > 39:
return False
if n >= 3:
a = 1
b = 1
for i in range(n-1):
a,b = b,a+b #这个是重点 复杂赋值 这个都没有用到i 是如何确定他会一直走下去的??
return a
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
result = [0,1]
if n <= 1:
return result[n]
for i in range(2,n+1):
result.append(result[i-1]+result[i-2])
return result[n]
方法2–递归实现
class Solution:
def Fibnacci(self, n):
if n <= 0:
return 0
if n == 1:
return 1
return self.Fibnacci(n-1) + self.Fibnacci(n-2)
- 题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
参考上一题做法
class Solution:
def jumpFloor(self, n):
if n <= 2:
return n
result = [0,1, 2]
for i in range(3, n + 1):
result.append(result[i - 1] + result[i - 2])
return result[n]
若把条件修改成一次可以跳一级,也可以跳2级…也可以跳上n级呢?
直接是2**(n-1)
题目6
题目描述
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
和跳台阶的问题一样的
题目7:
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路1:用两个数组
class Solution:
def reOrderArray(self, array):
l1=[]
l2=[]
for i in range(len(array)):
if array[i]%2==0:
l2.append(array[i])
else:
l1.append(array[i])
return l1+l2
# write code here
题目8::
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路–这种类型的通过字典映射
# -*- coding:utf-8 -*-
class Solution:
def MoreThanHalfNum_Solution(self, numbers):
dict={}
for num in numbers:
if num not in dict:
dict[num]=1
else:
dict[num]+=1
if dict[num]>len(numbers)/2:
return num
return 0
题目9:连续子数组的最大和
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
思路:1、第一个不为负数
2、如果前面数的累加值加上当前数后的值会比当前数小,说明累计值对整体和是有害的;如果前面数的累加值加上当前数后的值比当前数大或者等于,则说明累计值对整体和是有益的。
步骤:
1、定义两个变量,一个用来存储之前的累加值,一个用来存储当前的最大和。遍历数组中的每个元素,假设遍历到第i个数时:
①如果前面的累加值为负数或者等于0,那对累加值清0重新累加,把当前的第i个数的值赋给累加值。
②如果前面的累加值为整数,那么继续累加,即之前的累加值加上当前第i个数的值作为新的累加值。
2、判断累加值是否大于最大值:如果大于最大值,则最大和更新;否则,继续保留之前的最大和
class Solution:
def FindGreatestSumOfSubArray(self, array):
if len(array)<=0:
return []
temp=0
linum=[]
for i in array:
temp=temp+i 注意这个是加i
linum.append(temp)
if temp>0:
continue
else:
temp=0
return max(linum)
题目10
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路,转化为字符串进行比较,
# -*- coding:utf-8 -*-
if not numbers:
return ""
numbers = list(map(str, numbers))
numbers.sort(cmp=lambda x, y: cmp(x + y, y + x)) #降序排列
return "".join(numbers).lstrip('0') or'0'
题目11—数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
思路1:
第一反应是顺序扫描整个数组。每扫描到一个数组的时候,逐个比较该数字和它后面的数字的大小。如果后面的数字比它小,则这两个数字就组成了一个逆序对。假设数组中含有n个数字。由于每个数字都要和O(n)这个数字比较,因此这个算法的时间复杂度为O(n^2)。
def test(array):
t=0
for i in range(len(array)-1,0,-1):
flag=False
for j in range(i):
if array[j]>array[j+1]:
array[j],array[j+1]=array[j+1],array[j]
t+=1
flag=True
if not flag:
break
return t%(2*(10**5))
但是这个时间复杂度太高,过不了
下面是归并排序方法
from collections import deque
class Solution:
def __init__(self):
self.count = 0
def InversePairs(self, lis):
self.mergeSort(lis)
return self.count%1000000007
def mergeSort(self, lis):
if len(lis) <= 1:
return lis
middle = int(len(lis)//2)
left = self.mergeSort(lis[:middle])
right = self.mergeSort(lis[middle:])
return self.merge(left, right)
def merge(self, left,right):
merged,left,right = deque(),deque(left),deque(right)
while left and right:
if left[0] > right[0]:
self.count += len(left)
merged.append(right.popleft())
else:
merged.append(left.popleft())
if right:
merged.extend(right)
else:
merged.extend(left)
return merged
先将原序列排序,然后从排完序的数组中取出最小的,它在原数组中的位置表示有多少比它大的数在它前面,每取出一个在原数组中删除该元素,保证后面取出的元素在原数组中是最小的,这样其位置才能表示有多少比它大的数在它前面,即逆序对数。
class Solution:
def InversePairs(self, data):
count = 0
copy = []
for i in data:
copy.append(i)
copy.sort()
for i in range(len(copy)):
count += data.index(copy[i])
data.remove(copy[i])
return count%1000000007
a=[1,2,3,4,5,6,7,0]
Solution().InversePairs(a)
这个非常棒
题目12
统计一个数字在排序数组中出现的次数。
class Solution:
def GetNumberOfK(self, data, k):
dict={}
for num in data:
if num not in dict:
dict[num]=1
else:
dict[num]+=1
if k in dict:
return dict[k]
else:
return 0
参考前面的例题,统计超过一半的数字,或者直接
return data.count(k) #count() 方法用于统计某个元素在列表中出现的次数
题目13
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
也是使用字典
# -*- coding:utf-8 -*-
class Solution:
# 返回[a,b] 其中ab是出现一次的两个数字
def FindNumsAppearOnce(self, array):
hashMap = {}
for i in array:
if str(i) in hashMap:
hashMap[str(i)] += 1
else:
hashMap[str(i)] = 1
res = []
for k in hashMap.keys():
if hashMap[k] == 1:
res.append(int(k))
return res
# write code here
题目14-数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
按照上述类似的方法字典映射
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
dict={}
for num in numbers:
if num not in dict:
dict[num]=1
else:
dict[num]+=1
for k in dict:
if dict[k]>=2:
duplication[0]=k
return True
return False
# -*- coding:utf-8 -*-
class Solution:
def swap(self,array,i,j):
temp = array[i]
array[i] = array[j]
array[j] = temp
def duplicate(self, numbers, duplication):
length = len(numbers)
i=0
while i < length:
while numbers[i] != i:
if numbers[i] == numbers[numbers[i]]:
duplication[0] = numbers[i]
return True
self.swap(numbers,i,numbers[i])
i += 1
return False
题目15-构建乘积数组
给定一个数组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]。不能使用除法。
思路:
# -*- coding:utf-8 -*-
class Solution:
def multiply(self, A):
head = [1]
tail = [1]
for i in range(len(A)-1):
head.append(A[i]*head[i])
tail.append(A[-i-1]*tail[i])
return [head[j]*tail[-j-1] for j in range(len(head))]
# write code here