20、数组中的逆序对
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%100000000
示例1
输入
1,2,3,4,5,6,7,0
输出
7
笔记:题目很简单,然而按照写出来的,不能通过会超时,找了博客,看到的思路
更加简洁(牛逼)的方法:
先将原序列排序,然后从排完序的数组中取出最小的,它在原数组中的位置表示有多少比它大的数在它前面,每取出一个在原数组中删除该元素,保证后面取出的元素在原数组中是最小的,这样其位置才能表示有多少比它大的数在它前面,即逆序对数。
class Solution:
def InversePairs(self, data):
# write code here
if len(data) == 0 or len(data) == 1:
return 0
num = []
for i in data:
num.append(i)
num.sort()
c = 0
for i in range(len(num)):
p = data.index(num[i])
c += p
data.remove(num[i]) #deta.pop(p)
return c%1000000007
附上冒泡排序和快速排序python实现
#冒泡排序-------------------------------------------------------
def BubbleSort(list):
for i in reversed(range(len(a))):
for j in range(0,len(a)-1):
if(list[j] > list[j+1]):
temp=list[j]
list[j]=list[j+1]
list[j+1]=temp
def qsort(list):
if list==[]:
return []
else:
smaller=[x for x in list[1:] if x<list[0]] #比list[0]小的部分
bigger=[x for x in list[1:] if x>=list[0]] #比list[0]大(或相等)的部分
return qsort(smaller)+[list[0]]+qsort(bigger)
21、连续子数组的最大和
题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
解法1:自己的解法,总算可以做出一类题型了
# -*- coding:utf-8 -*-
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
num = []
for i in array:
num.append(i)
if len(num) == 1:
return num[0]
r = []
for i in range(len(num) - 1):
a = num[i]
for j in range(i + 1, len(num)):
a = a + num[j]
r.append(a)
r = r + num
r.sort()
return r[-1]
解法2:动态规划解法,得补一下知识,膜拜大神加油不要放弃你可以的
链接:https://www.nowcoder.com/questionTerminal/459bd355da1549fa8a49e350bf3df484 来源:牛客网
使用动态规划
F(i):以array[i]为末尾元素的子数组的和的最大值,子数组的元素的相对位置不变
F(i)=max(F(i-1)+array[i] , array[i])
res:所有子数组的和的最大值
res=max(res,F(i))
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
res = max(array)
temp = 0
for i in array:
temp = max(i, temp + i)
res = max(res ,temp)
return res
22、整数中1出现的次数
题目描述
求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)
笔记:解法1,自己想的,改了一次竟然真的可以通过,还好测试用例比较简单~~算了一种奇怪的解法吧
解法1:自己的不简洁版本
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
# write code here
num = []
for i in range(1, n + 1):
num.append(i)
c = 0
for j in range(n):
a = str(num[j])
c = c + a.count('1')
return c
解法2:
1位数,1-9中,1一共出现了1次;
2位数,10-99中,10-19的十位上一共出现了10*1=10次,对于每个十位开头的数字10-19、20-29,每个数个位上出现的是1-9中1出现的次数,共有9个区间9*1=9次;
3位数,100-999,100-199百位上出现了10**2=100次,对于每个百位数开头,例如100-199,200-299,低位上其实就是0-99这个区间上1出现的次数,一共9个区间 9*19=171次;
由此推测,对于1-9,10-99,100-999,每个n位数中包含1的个数公式为:
f(1) = 1
f(2) = 9 * f(1) + 10 ** 1
f(3) = 9 * f(2) + 10 ** 2
f(n) = 9 * f(n-1) + 10 ** (n-1)
通过以上分析,我们可以确定对于任意一个给定的数,例如23456这个5位数,10000之前的数中包含的个数是确定的了,为f(1)+f(2)+f(3)+f(4),这是一个递归的过程
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
# write code here
res=0
tmp=n
base=1
while tmp:
last=tmp%10
tmp=tmp/10
res+=tmp*base
if last==1:
res+=n%base+1
elif last>1:
res+=base
base*=10
return res
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
# write code here
count=0
i=1
while i<=n:
a=n/i
b=n%i
count+=(a+8)/10*i+(a%10==1)*(b+1)
i*=10
return count