时间效率(1-5)

题目描述1:数组中出现次数超过一半的数字

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

思路:
在遍历数组时保存两个值:一是数组中一个数字,一是次数。遍历下一个数字时,若它与之前保存的数字相同,则次数加1,否则次数减1;若次数为0,则保存下一个数字,并将次数置为1。遍历结束后,所保存的数字即为所求。然后再判断它是否符合条件即可。

Python测试:

// An highlighted block
def MoreThanHalfNum_Solution(numbers):
    len1 = len(numbers)
    if len1 == 0:
        return 0
    elif len1 >= 1:
        # 遍历每个元素,并记录次数;若与前一个元素相同,则次数加1,否则次数减1
        res = numbers[0]  # 初始值
        count = 1  # 次数
        for i in range(1, len1):
            if count == 0:
                # 更新result的值为当前元素,并置次数为1
                res = numbers[i]
                count = 1
            elif numbers[i] == res:
                count += 1  # 相同则加1
            elif numbers[i] != res:
                count -= 1  # # 不同则加1

        # 判断res是否符合条件,即出现次数大于数组长度的一半
        counts = 0
        for j in range(len1):
            if numbers[j] == res:
                counts += 1
        if counts > len1 // 2:  # python3整除为//,python2为/
            return res
        else:
            return 0


if __name__ == '__main__':
    try:
        while True:
            arr = [int(i) for i in input().split()]
            print(MoreThanHalfNum_Solution(arr))
    except:
        pass

题目描述2:最小的K个数

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

Python测试:

// An highlighted block
class Solution:
#归并排序,O(nLogn)
    def GetLeastNumbers_Solution(self, tinput, k):
        if len(tinput) < k:
            return []
        return self.merge_sort(tinput)[:k]

    def merge_sort(self, list):
        if len(list) < 2:
            return list[:]
        left = self.merge_sort(list[:len(list)//2])
        right = self.merge_sort(list[len(list)//2:])
        return self.merge(left,right)

    def merge(self,left, right):
        res = []
        while left and right:
              res.append(left.pop(0)) if left[0] < right[0] else res.append(right.pop(0))
        res += left if not right else right
        return res

if __name__ == '__main__':
    solution = Solution()
    seq = [1, 2, 4, 7, 3, 5, 6, 8]

    print(solution.GetLeastNumbers_Solution(seq, 4))

题目描述3:连续子数组的最大和

python测试1:

// An highlighted block
def function(lists):
    max_sum = lists[0]
    # print("max_sum: ", max_sum)
    pre_sum = 0
    for i in lists:
        if pre_sum < 0:
            pre_sum = i
            # print('pre_sum: ', pre_sum)
        else:
            pre_sum += i
            print('pre_sum: ', pre_sum)
        if pre_sum > max_sum:
            max_sum = pre_sum
    return max_sum


def main():
    lists = [6, -3,-2, 7, -15, 1, 2, 2]
    print(function(lists))

if __name__ == "__main__":
    main()

在这里插入图片描述

python测试2:

// An highlighted block
def function(lists):
    res = max(lists)
    temp = 0
    for i in lists:
        temp = max(i,temp+i)
        res = max(res, temp)

    return res

def main():
    lists = [6, -3,-2, 7, -15, 1, 2, 2]
    print(function(lists))


if __name__ == "__main__":
    main()

https://blog.csdn.net/HappyRocking/article/details/81348624

https://blog.csdn.net/u010636181/article/details/78422169

题目描述4:整数中1出现的次数(从1到n整数中1出现的次数)

思路:链接:https://www.nowcoder.com/questionTerminal/bd7f978302044eee894445e244c7eee6
来源:牛客网

注解:参考一位牛友提到的leetcode的链接网址(包括求1~n的所有整数中2,3,4,5,6,7,8,9出现的所有次数)
通过使用一个 位置乘子m 遍历数字的位置, m 分别为1,10,100,1000…etc.(m<=n)

对于每个位置来说,把10进制数分成两个部分,比如说 当m=100的时候, 把十进制数 n=3141592 分成 a=31415 和 b=92 ,以此来分析百位数为1时所有数的个数和。m=100时,百位数的前缀为3141,当百位数大于1时,为3142100,因为当百位数大于1时,前缀可以为0,即百位数可以从100到199,共100个数;当百位数不大于1时,为3141100;如何判断百位数是否大于1?假设百位数为x,若(x+8)/10等于1,则大于1,若(x+8)/10等于0,则小于1。因此前缀可用(n/m + 8)/10 m来计算(若计算2的个数,可以改为(n/m + 7)/10m,若计算3的个数,改为(n/m + 6)/10*m,…以此类推)。

再例如m=1000时,n分为a=3141和 b=592;千位数的前缀为314,千位数不大于1,故前缀计算为3141000;因为千位数为1,再加b+1(0到592)。即千位数为1的所有书的个数和为3141000+592+1;公式(n/m + 8)/10*m + b +1。

注意:只有n的第m位为1时需要计算后缀,后缀计算为 (n/m%10==1)*(b+1),

即(n/m%10 == 1)判断第m位是否为1,若为1,则加上(b+1),若不为1,则只计算前缀。(若计算2的个数,可以改为(n/m%10==2)(b+1),若计算3的个数,可以改为(n/m%10 == 3)(b+1)…以此类推)

// An highlighted block
// An highlighted block
# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1Between1AndN_Solution(self, n):
        ones, m = 0, 1
        while m <= n:
            ones += (n // m + 8) // 10 * m + (n // m % 10 == 1) * (n % m + 1)
            m *= 10
        return ones
if __name__ == "__main__":

    a = Solution()

    print(a.NumberOf1Between1AndN_Solution(30))

https://blog.csdn.net/huzhigenlaohu/article/details/51779365

题目描述5:把数组排成最小的数

// An highlighted block
from functools import cmp_to_key

class Solution:
    def cmp(self,a,b):
        if a+b>b+a:
            return 1
        if a+b<b+a:
            return -1
        else:
            return 0

    def PrintMinNumber(self,numbers):
        if not numbers:
            return ""
        number = list(map(str,numbers))
        number.sort(key=cmp_to_key(self.cmp))
        print("number: ", number)
        return "".join(number).lstrip('0') or '0'
so = Solution()
print(so.PrintMinNumber([3,32,321]))

总结

数组中出现次数超过一半的数字:
https://blog.csdn.net/qq_38441207/article/details/88708889
最小的K个数:
https://blog.csdn.net/qq_38441207/article/details/88709145
连续子数组的最大和:
https://blog.csdn.net/qq_38441207/article/details/88716033
整数中1出现的次数(从1到n整数中1出现的次数):
https://blog.csdn.net/qq_38441207/article/details/88717199
把数组排成最小的数:
https://blog.csdn.net/qq_38441207/article/details/88718565

猜你喜欢

转载自blog.csdn.net/qq_38441207/article/details/89070257
今日推荐