目录
最大乘积(贪心,拼多多,中等)
题目描述
给定一个无序数组,包含正数、负数和0,要求从中找出3个数的乘积,使得乘积最大,要求时间复杂度:O(n),空间复杂度:O(1)
输入描述:
输入共2行,第一行包括一个整数n,表示数组长度
第二行为n个以空格隔开的整数,分别为A1,A2, … ,An
输出描述:
满足条件的最大乘积
示例1
输入
4
3 4 1 2
输出
24
思路
看到题没思路。依次取到当前序列中的最大值,取到之后,找次最大值(将最大值从序列中删去,再找最大值),再找次次最大值,求出它们的乘积。接着,按同样方法,再在初始序列中找最小值,次最小值,次次最小值,求它们的乘积,两次结果取最大。
1.这样的做法等同于先把序列排好序,然后,取首尾的值,我们按首来考虑,
如果该序列的最大值为正,并且只有这一个为正,那么首的三个数乘积一定是最大值,因为尾的三个数乘积肯定是负数,其他任意三个数连乘也肯定是负数。
如果该序列的只有首的前两个数为正,那么首三乘积就是负的了,尾三乘积也是负的,到底谁大,就要比比了,因为负数是越往模越大值越小。
如果该序列的至少前三个值正,也需要跟尾三数乘积比比,万一尾三乘积乘出的是个正数,不一定比首三乘积的小。
综上所述,不哔哔了,首三乘积和尾三乘积是主要考虑的对象,中间的元素是不需要考虑的。
2.这里用到了copy的操作,lstcopy=lst[:]是浅拷贝,但并不影响整个结果,这里提个醒。
3.记住序列删除某个指定元素的操作,lst.remove(max)
4.求最大最小值的函数max,min
5.我有个疑问,要求时间复杂度是O(n),那sort()函数排序的时间复杂度竟然这么快啊?
订正:并不是简单的首三乘积和尾三乘积,上面说错了,经过测试发现,分析的思路应该是这样的:如果求最大的乘积,按有正数的情况来考虑,如果,一个按顺序排列后,一般而言,如果比较的数字大于3个,那么:
组合一:最大的三个正数,
组合二:最小的两个负数加最大的一个正数
最大值只会在这两种组合中,出现,想想是不是?
code
版本一
n = int(raw_input().strip())
lst = list(map(int, raw_input().strip().split()))
max1 = max(lst)
lst.remove(max1)
lstcopy = lst[:]
max2 = max(lst)
lst.remove(max2)
max3 = max(lst)
min1 = min(lstcopy)
lstcopy.remove(min1)
min2 = min(lstcopy)
lstcopy.remove(min2)
print(max(max1*max2*max3, min1*min2*max1))
版本二
n = int(raw_input())
nums = map(int,raw_input().split())
nums.sort()
print max(nums[0]*nums[1]*nums[-1],nums[-1]*nums[-2]*nums[-3])
六一儿童节(贪心,拼多多)
题目描述
六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]>=h[i]),他才会上去表演节目。老师的目标是将巧克力分发给孩子们,使得最多的小孩上台表演。可以保证每个w[i]> 0且不能将多块巧克力分给一个孩子或将一块分给多个孩子。
输入描述:第一行:n,表示h数组元素个数 第二行:n个h数组元素 第三行:m,表示w数组元素个数 第四行:m个w数组元素
输出描述:上台表演学生人数
示例1
输入
3
2 2 3
2
3 1
输出
1
思路
我的思路是,将两个序列先升序排好,然后,逐个分布设置两个指针开始比较,a指向小朋友,b指向巧克力,如果当前比较的巧克力可以满足小朋友的需求,就count +=1,然后,将a,b都向后移动,如果b,不满足当前小朋友的需求,那么a不动,b向后移动,依次遍历,直到小朋友序列或者巧克力序列有一个循环完,返回count.
看正确思路,吻合。
code
#-*- coding:utf-8 -*-
def solve():
n = input() # 表示h数组元素个数,学生人数
h = map(int, raw_input().split()) # n个h数组元素,每个学生所需的巧克力
m = input() # 表示w数组元素个数,m个巧克力
w = map(int, raw_input().split()) # m个h数组元素,每个巧克力的重量
h.sort(reverse=True) # p
w.sort(reverse=True) # k
k, p, res = 0, 0, 0
while (k < m and p < n):
if w[k] >= h[p]:
res += 1
k += 1
p += 1
else:
p += 1
return res
if __name__ == "__main__":
print(solve())
彩色的砖块(巧思考,网易)
题目描述
小易有一些彩色的砖块。每种颜色由一个大写字母表示。各个颜色砖块看起来都完全一样。现在有一个给定的字符串s,s中每个字符代表小易的某个砖块的颜色。小易想把他所有的砖块排成一行。如果最多存在一对不同颜色的相邻砖块,那么这行砖块就很漂亮的。请你帮助小易计算有多少种方式将他所有砖块排成漂亮的一行。(如果两种方式所对应的砖块颜色序列是相同的,那么认为这两种方式是一样的。)
例如: s = "ABAB",那么小易有六种排列的结果:
"AABB","ABAB","ABBA","BAAB","BABA","BBAA"
其中只有"AABB"和"BBAA"满足最多只有一对不同颜色的相邻砖块。
输入描述:
输入包括一个字符串s,字符串s的长度length(1 ≤ length ≤ 50),s中的每一个字符都为一个大写字母(A到Z)。
输出描述:
输出一个整数,表示小易可以有多少种方式。
示例1
输入
ABAB
输出
2
思路
我的思路是先全排列,然后遍历每个排列,设置一个标识符count为0。每次如果当前元素和后面元素不同就加1,最后,遍历结束后后,如果count = 1 或者count = 0,则再总计数res里加一,统计数量。但这个的思路时间复杂度肯定超。
再看正确的思路,先将序列出现的元素种类统计出来,如果元素种类大于2,怎么排列也无法排成最多只有一对不同颜色的相邻砖块。
如果等于2类,那肯定是只有两种排列可能,
如果只有1类,那不用说了,肯定只有一种。
综上所述,我好傻— —||。
code
def differentChar(str):
if str == None or len(str) <= 0:
return 0
new_str = []
for item in str:
if item not in new_str:
new_str.append(item)
if len(new_str) == 1:
return 1
elif len(new_str) == 2:
return 2
else:
return 0
if __name__ == "__main__":
str = raw_input()
print(differentChar(str))
等差数列(思考,网易)
题目描述
如果一个数列S满足对于所有的合法的i,都有S[i + 1] = S[i] + d, 这里的d也可以是负数和零,我们就称数列S为等差数列。
小易现在有一个长度为n的数列x,小易想把x变为一个等差数列。小易允许在数列上做交换任意两个位置的数值的操作,并且交换操作允许交换多次。但是有些数列通过交换还是不能变成等差数列,小易需要判别一个数列是否能通过交换操作变成等差数列
输入描述:
输入包括两行,第一行包含整数n(2 ≤ n ≤ 50),即数列的长度。
第二行n个元素x[i](0 ≤ x[i] ≤ 1000),即数列中的每个整数。
输出描述:
如果可以变成等差数列输出"Possible",否则输出"Impossible"。
示例1
输入
3 3 1 2
输出
Possible
思路
一看没思路。一看正确的解,想骂人,我主要被困住的地方是:“小易允许在数列上做交换任意两个位置的数值的操作,并且交换操作允许交换多次。”我实在是思考不出来这个条件怎么用,合着对应的就是将数列排下顺序!然后,依次求差,如果差都相等,就是等差数列!
code
a = int(raw_input(""))
b = map(int,raw_input("").split(" "))
c = sorted(b)
res = []
for i in range(len(c)-1):
res.append(c[i+1]-c[i])
if len(set(res)) == 1:
print 'Possible'
else:
print 'Impossible'
交错01串(字符串,网易)
题目描述
如果一个01串任意两个相邻位置的字符都是不一样的,我们就叫这个01串为交错01串。例如: "1","10101","0101010"都是交错01串。小易现在有一个01串s,小易想找出一个最长的连续子串,并且这个子串是一个交错01串。小易需要你帮帮忙求出最长的这样的子串的长度是多少。
输入描述:
输入包括字符串s,s的长度length(1 ≤ length ≤ 50),字符串中只包含'0'和'1'
输出描述:
输出一个整数,表示最长的满足要求的子串长度。
示例1
输入
111101111
输出
3
思路
我的思路是遍历字符串,if:s[i] != s[i+1] ->count += 1,else: res.append(count),count = 0,最后,把res里保存的最大值输出就行了。
对比一下正确的思路,是吻合的,唯一美中不足的是,我默认的是从0开始累加,正确的是从1开始累加,因为计数长度的确是从1开始计数的。
code
ss = raw_input()
k = 1
K = []
for i in range(0, len(ss)-1):
if ss[i] != ss[i + 1]:
k += 1
K.append(k)
else:
k = 1
if K:
print(max(K))
else:
print(1)