剑指Offer(Python语言)面试题39,40

面试题39:数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现5次,超过数组长度的一半,因此输出2。

解法1:基于Partition函数的时间复杂度为O(n)的算法
     * 将数组进行排序,若是某个数字在数组中超过一半,
     *那么排序后的中间位置的数字就是要找的那个重复的数字
     *使用快速排序的方法,将其进行排序  找到中间的,
     *并且使用一个函数再对该数字进行检验,查看重复量是否超过了一半

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if not numbers:
            return numbers
        
        def recc(begin, end):
            if begin >= end:
                return numbers[begin]
            index = begin
            for i in range(begin+1, end+1):
                if numbers[index] > numbers[i]:
                    numbers[index], numbers[i] = numbers[i], numbers[index]
                    index = i 
            if index == length >> 1:
                return numbers[index]
            if index > length >> 1:
                num = recc(begin, index-1)
            else:
                num = recc(index+1, end)
            return num
        
        length = len(numbers)
        number = recc(0, length-1)
        counts = 0
        for i in range(length):
            if number == numbers[i]:
                counts += 1
        if counts > length >> 1:
            return number
        return 0

解法2:根据数组特点找出时间复杂度为O(n)的算法

遍历数组保留两个值:一个是数组中的一个数字,另一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1;如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为0,那么我们需要保存下一个数字,并把次数设为1。

class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if not numbers:
            return numbers
        current_number =None
        counts = 0
        index = 0
        while index < len(numbers):
            if counts == 0:
                current_number = numbers[index]
                counts += 1
            elif current_number == numbers[index]:
                counts += 1
            else:
                counts -= 1
            index += 1
        if counts > 1:
            return current_number
        counts = 0
        for number in numbers:
            if number == current_number:
                counts += 1
        if counts > len(numbers) >> 1:
            return current_number
        return 0

面试题40:最小的K个数

题目:输入n个整数,找出其中最小的K个数。例如,输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

解题思路
  可以创建一个大小为k的数据容器来存储最小的k个数字,然后每次从输入的n个整数中读入一个数。每次拿读入的数与当前容器中最大值比较,若读入的数小于最大值,则将其加入容器中,并对容器排序,最后抛弃容器中最大值;若读入的数大于最大值,直接抛弃,然后继续读入下一个数。容器的最佳实现是使用最大堆,但下面我们直接用Python提供的排序函数。
 

class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        if not tinput or k <= 0 or k > len(tinput):
            return []
            
        results = sorted(tinput[:k])
        for number in tinput[k:]:
            if number < results[-1]:
                results.append(number)
                results = sorted(results)
                results = results[:-1]
            
        return results

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤凰AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值