语言python,为牛客第二版的四道题
最小的K个数
连续子数组的最大和
把数组排成最小的数
第一个只出现一次的字符
1、最小的K个数
最小的K个数
题目描述 输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路: 解法1:暴力解法当然可以做(先从小到大排序,在取前k个),但是时间复杂度为n的2次方.
解法2: 选择排序的基础上改进,不全部遍历,前k趟,每一轮都可以选出后面最小的。时间复杂度k*n,可以看成是n
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
if not tinput:
return []
# 注意:要处理当k值比输入的数组长度还长时的报错
if len(tinput) < k:
return []
for i in range(0, k):
for j in range(len(tinput)-1, i, -1):
if tinput[j] < tinput[i]:
tinput[j], tinput[i] = tinput[i], tinput[j]
return tinput[:k]
2、
连续子数组的最大和
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
思路 : 要求连续大和,去判断前面的累加和对于当前即将更新时的值是否是正向影响,并记录历史最大值。对于新获得的一个数,看当前已有的累加和A如果小于0,说明此时历史带来的是负面影响,直接抛弃历史原和,将A更新为当前数;如果A大于0,则A加上当前数。更新A之后,如果A大于B则更新B,否则继续读下一个数。(注意:A<0抛弃历史,A可以更新为当前数,但B不可以直接更新,因为B记录的是历史最大值)
import sys
class Solution:
def FindGreatestSumOfSubArray(self, array):
# write code here
if not array:
return 0
current_sum = sys.maxsize * -1
max_sum = current_sum
for i in array:
if current_sum < 0:
current_sum = i
else:
current_sum += i
if current_sum > max_sum:
max_sum = current_sum
return max_sum
3 、把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路: 具体细节比较利用字符串的排序,整体中Python中可以自定义排序的方法
# -*- coding:utf-8 -*-
class Solution:
#转换为字符串,python 的sort可以自定义,主要看方式
def PrintMinNumber(self, numbers):
if not numbers:
return ""
str_list = [str(n) for n in numbers]
# python中,sort可以传入自定义的排序方法
str_list.sort(self.Sort)
return int(''.join(str_list))
def Sort(self, x, y):
# 如何判断3和32谁应该排在前面呢?
# 只要将他俩正反拼接一下,就知道了!这个排序的比较方法很骚气,完全不需要定义什么复杂的字典序规则!
left = x + y
right = y + x
if left > right:
return 1
else:
return -1
4、第一个只出现一次的字符
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写)
思路: 构建字符与字符出现次数的字典,在遍历找出值为1的
# -*- coding:utf-8 -*-
class Solution:
def FirstNotRepeatingChar(self, s):
# write code here
# 一行解决
#return s.index(list(filter(lambda c:s.count(c)==1,s))[0]) if s else -1
if not s:
return -1
dic = {}
for char in s:
if char in dic:
dic[char] += 1
else:
dic[char] = 1
for index, char in enumerate(s):
if dic[char] == 1:
return index