剑指offer刷题0401

本文解析了牛客网上四道经典算法题:最小的K个数、连续子数组的最大和、把数组排成最小的数及第一个只出现一次的字符。通过详细阐述解题思路与代码实现,帮助读者理解算法设计原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

语言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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值