LintCode刷起来(一)

本文介绍了如何解决LintCode平台上的三个经典问题,包括A+B的加法运算、尾部零的数量计算以及数字统计。同时,展示了不同方法优化后的代码,如使用内置函数、迭代优化和堆排序算法。最后,讲解了丑数II的高效枚举策略和利用堆数据结构的解题思路。
摘要由CSDN通过智能技术生成

LintCode刷起来(一)

1. A + B 问题

  • 方法一:
class Solution:
    """
    @param a: An integer
    @param b: An integer
    @return: The sum of a and b 
    """
    def aplusb(self, a, b):
        # write your code here
        return a + b
  • 方法二:
class Solution:
    """
    @param a: An integer
    @param b: An integer
    @return: The sum of a and b 
    """
    def aplusb(self, a, b):
        # write your code here
        return sum([a, b])
  • 方法三:
from operator import add

class Solution:
    """
    @param a: An integer
    @param b: An integer
    @return: The sum of a and b 
    """
    def aplusb(self, a, b):
        # write your code here
        return add(a, b)

2 · 尾部的零

大佬救命,大佬饶命
大佬还是大佬,太强了。想要知道有多少个0也就是里面有这n个数可以拆分出来多少个2和5。很显然5的个数远远小于2的个数,所以这n个数可以拆分出来多少个5也就是多少个0.
不得不说大佬思路太强了。下面也就是找1234···n-1n里面可以拆分出多少个5了很显然5的倍数必定可以拆分出至少一个5,同时25的倍数可以拆分出至少两个5,依次类推,5^i次方至少可以拆分出来i个5,我们可以第一次只统计5的倍数,然后5 ^ 2的倍数依次类推到5 ^ i的倍数,所有个数加起来即可。

class Solution:
    """
    @param n: A long integer
    @return: An integer, denote the number of trailing zeros in n!
    """
    def trailingZeros(self, n):
        # write your code here
        num = 0
        i = 5
        while n>=i:
            num += n//i
            i = i * 5
        return num

3 · 统计数字

  • 方法一:偷个懒直接用python的内置函数 cout来做,可以用来查找一个字符串中指定字符的个数
class Solution:
    """
    @param k: An integer
    @param n: An integer
    @return: An integer denote the count of digit k in 1..n
    """
    def digitCounts(self, k, n):
        # write your code here
        result = 0
        for item in range(0, n+1):
            number = str(item).count(str(k))
            result += number
        return result
  • 方法二:
    笨笨的方法对每个数都进行统计,能力所限,懒得优化了,据大佬说可以优化到O(logN)
class Solution:
    """
    @param k: An integer
    @param n: An integer
    @return: An integer denote the count of digit k in 1..n
    """
    def digitCounts(self, k, n):
        # write your code here
        result = 0
        if k == 0 :
            result += 1
        for i in range(n+1):
            temp = i
            while temp:
                if temp % 10 == k:
                    result +=1
                temp//=10
        return result
  • 方法三:大佬的方法,感兴趣的看看就好
class Solution:
    """
    @param: : An integer
    @param: : An integer
    @return: An integer denote the count of digit k in 1..n
    """

    def digitCounts(self, k, n):
        
        def ten(power):
            return 10**power
            
        digits = self.getNumOfDigits(n)
        
        ans = 0
        
        if k == 0:
            for i in range(digits-1):
                ans += (n // ten(i+1) -1) * ten(i)
                ans += min(n % ten(i+1), ten(i) - 1) + 1

            ans += 1
        else:
            for i in range(digits):
                ans += n // ten(i+1) * ten(i)
                ans += max(0, min( (k+1)*ten(i)-1, n%ten(i+1) ) - k*ten(i) + 1)
        
        return ans
    
    @staticmethod
    def getNumOfDigits(n):
        if n == 0:
            return 1
            
        count = 0
        while n:
            count += 1
            n //= 10
        return count

4 · 丑数 II

其实思路很明确也很简单,枚举肯定最麻烦而且也不可取。由于整数均可以划分为素数不同幂次的乘积且只有一种情况。只有质因子2、3、5所以它必定是这三个数的不同幂次的乘积,所以我们只需要有效到大依次找到并且第N个就好了。

class Solution:
    """
    @param n: An integer
    @return: the nth prime number as description.
    """
    def nthUglyNumber(self, n):
        # write your code here
        heap = [1]
        p2,p3,p5 = 0,0,0
        for i in range(n - 1):
            last = heap[-1]
            while heap[p2] * 2 <= last:
                p2 += 1
            while heap[p3] * 3 <= last:
                p3 += 1
            while heap[p5] * 5 <= last:
                p5 += 1
            
            heap.append(min(heap[p2] * 2, heap[p3] * 3, heap[p5] * 5))
            
        return heap[-1]

我看网上还有一种堆排序的算法也是可以的
seen采用元组的因为查找方便,运用了空间换时间的方法
求第n小的丑数,可以采用最小堆来解决。每次弹出堆中最小的丑数,然后检查它分别乘以2、3和 5后的数是否生成过,如果是第一次生成,那么就放入堆中。第n个弹出的数即为第n小的丑数。
至于为什么要判断是否生成过,因为如果最小为2的时候4,6,10会放入,但是当最小为3时6,9,10也会放入,同理5最小时10,15,25也会放入。这样可以将重复的6和10排除,方便堆排序

import heapq

class Solution:
    """
    @param n: An integer
    @return: return a  integer as description.
    """
    def nthUglyNumber(self, n):
        heap = []
        heapq.heappush(heap, 1)

        seen = set()
        seen.add(1)

        factors = [2, 3, 5]

        curr_ugly = 1
        
        for _ in range(n):
            # 每次弹出当前最小丑数
            curr_ugly = heapq.heappop(heap)
            # 生成新的丑数
            for f in factors:
                new_ugly = curr_ugly * f
                if new_ugly not in seen:
                    seen.add(new_ugly)
                    heapq.heappush(heap, new_ugly)
        return curr_ugly
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值