国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)

這篇具有很好參考價(jià)值的文章主要介紹了每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

關(guān)于最大公約數(shù)有專門的研究。 而在 LeetCode 中雖然沒有直接讓你求解最大公約數(shù)的題目。但是卻有一些間接需要你求解最大公約數(shù)的題目。

每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)

如何求最大公約數(shù)?

定義法

def GCD(a: int, b: int) -> int:
    smaller = min(a, b)
    while smaller:
        if a % smaller == 0 and b % smaller == 0:
            return smaller
        smaller -= 1

復(fù)雜度分析

  • 時(shí)間復(fù)雜度:最好的情況是執(zhí)行一次循環(huán)體,最壞的情況是循環(huán)到 smaller 為 1,因此總的時(shí)間復(fù)雜度為 O ( N ) O(N) O(N),其中 N 為 a 和 b 中較小的數(shù)。
  • 空間復(fù)雜度: O ( 1 ) O(1) O(1)。

輾轉(zhuǎn)相除法

如果我們需要計(jì)算 a 和 b 的最大公約數(shù),運(yùn)用輾轉(zhuǎn)相除法的話。
首先,我們先計(jì)算出 a 除以 b 的余數(shù) c,把問題轉(zhuǎn)化成求出 b 和 c 的最大公約數(shù);
然后計(jì)算出 b 除以 c 的余數(shù) d,把問題轉(zhuǎn)化成求出 c 和 d 的最大公約數(shù);
再然后計(jì)算出 c 除以 d 的余數(shù) e,把問題轉(zhuǎn)化成求出 d 和 e 的最大公約數(shù)。

以此類推,逐漸把兩個(gè)較大整數(shù)之間的運(yùn)算轉(zhuǎn)化為兩個(gè)較小整數(shù)之間的運(yùn)算,直到兩個(gè)數(shù)可以整除為止。

def GCD(a: int, b: int) -> int:
    return a if b == 0 else GCD(b, a % b)

每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)

更相減損術(shù)

輾轉(zhuǎn)相除法如果 a 和 b 都很大的時(shí)候,a % b 性能會(huì)較低。在中國,《九章算術(shù)》中提到了一種類似輾轉(zhuǎn)相減法的 更相減損術(shù)。它的原理是:兩個(gè)正整數(shù) a 和 b(a>b),它們的最大公約數(shù)等于 a-b 的差值 c 和較小數(shù) b 的最大公約數(shù)

def GCD(a: int, b: int) -> int:
    if a == b:
        return a
    if a < b:
        return GCD(b - a, a)
    return GCD(a - b, b)

上面的代碼會(huì)報(bào)棧溢出。原因在于如果 a 和 b 相差比較大的話,遞歸次數(shù)會(huì)明顯增加,要比輾轉(zhuǎn)相除法遞歸深度增加很多,最壞時(shí)間復(fù)雜度為 O(max(a, b)))。這個(gè)時(shí)候我們可以將輾轉(zhuǎn)相除法和更相減損術(shù)做一個(gè)結(jié)合,從而在各種情況都可以獲得較好的性能。

形象化解釋

下面我們對(duì)上面的過程進(jìn)行一個(gè)表形象地講解,實(shí)際上這也是教材里面的講解方式,我只是照搬過來,增加一下自己的理解罷了。我們來通過一個(gè)例子來講解:

假如我們有一塊 1680 米 * 640 米 的土地,我們希望將其分成若干正方形的土地,且我們想讓正方形土地的邊長盡可能大,我們應(yīng)該如何設(shè)計(jì)算法呢?

實(shí)際上這正是一個(gè)最大公約數(shù)的應(yīng)用場景,我們的目標(biāo)就是求解 1680 和 640 的最大公約數(shù)。

每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)
將 1680 米 * 640 米 的土地分割,相當(dāng)于對(duì)將 400 米 * 640 米 的土地進(jìn)行分割。 為什么呢? 假如 400 米 * 640 米分割的正方形邊長為 x,那么有 640 % x == 0,那么肯定也滿足剩下的兩塊 640 米 * 640 米的。

每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)
每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)

實(shí)例解析

題目描述

給你三個(gè)數(shù)字 a,b,c,你需要找到第 n 個(gè)(n 從 0 開始)有序序列的值,
這個(gè)有序序列是由 a,b,c 的整數(shù)倍構(gòu)成的。

比如:
n = 8
a = 2
b = 5
c = 7

由于 2,5,7 構(gòu)成的整數(shù)倍構(gòu)成的有序序列為 [1, 2, 4, 5, 6, 7, 8, 10, 12, ...],因此我們需要返回 12。

注意:我們約定,有序序列的第一個(gè)永遠(yuǎn)是 1。

大家可以通過 這個(gè)網(wǎng)站 在線驗(yàn)證。
一個(gè)簡單的思路是使用堆來做,唯一需要注意的是去重,我們可以使用一個(gè)哈希表來記錄出現(xiàn)過的數(shù)字,以達(dá)到去重的目的。

代碼:

ss Solution:
    def solve(self, n, a, b, c):
        seen = set()
        h = [(a, a, 1), (b, b, 1), (c, c, 1)]
        heapq.heapify(h)

        while True:
            cur, base, times = heapq.heappop(h)
            if cur not in seen:
                n -= 1
                seen.add(cur)
            if n == 0:
                return cur
            heapq.heappush(h, (base * (times + 1), base, times + 1))

對(duì)于此解法不理解的可先看下我之前寫的 幾乎刷完了力扣所有的堆題,我發(fā)現(xiàn)了這些東西。。。(第二彈)

然而這種做法時(shí)間復(fù)雜度太高,有沒有更好的做法呢?

實(shí)際上,我們可對(duì)搜索空間進(jìn)行二分。首先思考一個(gè)問題,如果給定一個(gè)數(shù)字 x,那么有序序列中小于等于 x 的值有幾個(gè)。
答案是 x // a + x // b + x // c 嗎?

// 是地板除

可惜不是的。比如 a = 2, b = 4, n = 4,答案顯然不是 4 // 2 + 4 // 4 = 3,而是 2。這里出錯(cuò)的原因在于 4 被計(jì)算了兩次,一次是 2 ? 2 = 4 2 * 2 = 4 2?2=4,另一次是 4 ? 1 = 4 4 * 1 = 4 4?1=4。

為了解決這個(gè)問題,我們可以通過集合論的知識(shí)。

一點(diǎn)點(diǎn)集合知識(shí):

  • 如果把有序序列中小于等于 x 的可以被 x 整除,且是 a 的倍數(shù)的值構(gòu)成的集合為 SA,集合大小為 A
  • 如果把有序序列中小于等于 x 的可以被 x 整除,且是 b 的倍數(shù)的值構(gòu)成的集合為 SB,集合大小為 B
  • 如果把有序序列中小于等于 x 的可以被 x 整除,且是 c 的倍數(shù)的值構(gòu)成的集合為 SC,集合大小為 C

那么最終的答案就是 SA ,SB,SC 構(gòu)成的大的集合(需要去重)的中的數(shù)字的個(gè)數(shù),也就是:
每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)
問題轉(zhuǎn)化為 A 和 B 集合交集的個(gè)數(shù)如何求?

實(shí)際上, SA 和 SB 的交集個(gè)數(shù)就是 x // lcm(A, B),其中 lcm 為 A 和 B 的最小公倍數(shù)。而最小公倍數(shù)則可以通過最大公約數(shù)計(jì)算出來:

def lcm(x, y):
    return x * y // gcd(x, y)

接下來就是二分套路了,二分部分看不懂的建議看下我的二分專題。

代碼(Python3):

class Solution:
    def solve(self, n, a, b, c):
        def gcd(x, y):
            if y == 0:
                return x
            return gcd(y, x % y)

        def lcm(x, y):
            return x * y // gcd(x, y)

        def possible(mid):
            return (mid // a + mid // b + mid // c - mid // lcm(a, b) - mid // lcm(b, c) - mid // lcm(a, c) + mid // lcm(a, lcm(b, c))) >= n

        l, r = 1, n * max(a, b, c)
        while l <= r:
            mid = (l + r) // 2
            if possible(mid):
                r = mid - 1
            else:
                l = mid + 1
        return l

每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)文章來源地址http://www.zghlxwxcb.cn/news/detail-435171.html

到了這里,關(guān)于每天一道算法練習(xí)題--Day22&& 第一章 --算法專題 --- ----------最大公約數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)據(jù)庫系統(tǒng)概述——第一章 緒論(知識(shí)點(diǎn)復(fù)習(xí)+練習(xí)題)

    數(shù)據(jù)庫系統(tǒng)概述——第一章 緒論(知識(shí)點(diǎn)復(fù)習(xí)+練習(xí)題)

    ? 博主: 命運(yùn)之光 ?? 專欄: 離散數(shù)學(xué)考前復(fù)習(xí)(知識(shí)點(diǎn)+題) ?? 專欄: 概率論期末速成(一套卷) ?? 專欄: 數(shù)字電路考前復(fù)習(xí) ?? 專欄: 數(shù)據(jù)庫系統(tǒng)概述 ? 博主的其他文章: 點(diǎn)擊進(jìn)入博主的主頁????? 前言: 身為大學(xué)生考前復(fù)習(xí)一定十分痛苦,你有沒有過以

    2024年02月09日
    瀏覽(25)
  • 《Lua程序設(shè)計(jì)第四版》 第一部分自做練習(xí)題答案

    Lua程序設(shè)計(jì)第四版第一部分語言基礎(chǔ)自做練習(xí)題答案,帶?為重點(diǎn)。 運(yùn)行階乘的示例并觀察,如果輸入負(fù)數(shù),程序會(huì)出現(xiàn)什么問題?試著修改代碼來解決問題 輸入負(fù)數(shù),程序會(huì)死循環(huán),修改如下 分別使用-l參數(shù)和dofile運(yùn)行twice示例,并感受你喜歡哪種方式 載入庫,在 lua解釋

    2024年02月13日
    瀏覽(96)
  • 《Lua程序設(shè)計(jì)第四版》 第一部分前8章自做練習(xí)題答案

    Lua程序設(shè)計(jì)第四版第一部分語言基礎(chǔ)自做練習(xí)題答案,帶?為重點(diǎn)。 運(yùn)行階乘的示例并觀察,如果輸入負(fù)數(shù),程序會(huì)出現(xiàn)什么問題?試著修改代碼來解決問題 輸入負(fù)數(shù),程序會(huì)死循環(huán),修改如下 分別使用-l參數(shù)和dofile運(yùn)行twice示例,并感受你喜歡哪種方式 載入庫,在 lua解釋

    2024年02月13日
    瀏覽(155)
  • 練習(xí)題----順序棧算法

    練習(xí)題----順序棧算法

    ?輸入一個(gè)包括 \\\'(\\\' 和 \\\')\\\' 的字符串string ,判斷字符串是否有效。要求設(shè)計(jì)算法實(shí)現(xiàn)檢查字符串是否有效,有效的字符串需滿足以下條件: A. 左括號(hào)必須用相同類型的右括號(hào)閉合。 B. 左括號(hào)必須以正確的順序閉合。 C. 每個(gè)右括號(hào)都有一個(gè)對(duì)應(yīng)的相同類型的左括號(hào)。 ?該題需

    2024年04月26日
    瀏覽(25)
  • <算法學(xué)習(xí)>動(dòng)態(tài)規(guī)劃練習(xí)題

    <算法學(xué)習(xí)>動(dòng)態(tài)規(guī)劃練習(xí)題

    本篇文章為初學(xué)動(dòng)態(tài)規(guī)劃時(shí)的練習(xí)題。參考優(yōu)質(zhì)博客學(xué)習(xí)后根據(jù)偽代碼描述完成代碼。記錄一下用于以后復(fù)習(xí)。 給定一個(gè)有n行數(shù)字組成的數(shù)字三角形. 試設(shè)計(jì)一個(gè)算法, 計(jì)算出從三角形的頂至底的一條路徑, 使該路徑經(jīng)過的數(shù)字和最大. 算法設(shè)計(jì): 對(duì)于給定的n行數(shù)字組成的三角

    2024年01月17日
    瀏覽(18)
  • Matlab:遺傳算法,模擬退火算法練習(xí)題

    Matlab:遺傳算法,模擬退火算法練習(xí)題

    1、遺傳算法 (1) 遺傳算法 是一種基于自然選擇原理和自然遺傳機(jī) 制的搜索(尋優(yōu))算法,它是模擬自然界中的生命進(jìn)化機(jī)制,在人工系統(tǒng)中實(shí)現(xiàn)特定目 標(biāo)的優(yōu)化。遺傳算法的實(shí)質(zhì)是通過群體搜索技術(shù),根據(jù)適者生存的原則逐代進(jìn)化,最終 得到最優(yōu)解或準(zhǔn)最優(yōu)解。它必須

    2024年01月21日
    瀏覽(29)
  • 拓?fù)渑判?(算法思想+圖解+模板+練習(xí)題)

    拓?fù)渑判?(算法思想+圖解+模板+練習(xí)題)

    有向無環(huán)圖一定是拓?fù)湫蛄?有向有環(huán)圖一定不是拓?fù)湫蛄小?無向圖沒有拓?fù)湫蛄小?首先我們先來解釋一下什么是有向無環(huán)圖: 有向就是我們兩個(gè)結(jié)點(diǎn)之間的邊是有方向的,無環(huán)的意思就是整個(gè)序列中沒有幾個(gè)結(jié)點(diǎn)通過邊形成一個(gè)圓環(huán)。 下圖就是一個(gè)有向無環(huán)圖,它也一定

    2024年02月03日
    瀏覽(27)
  • 【算法設(shè)計(jì)與分析】動(dòng)態(tài)規(guī)劃-練習(xí)題

    【算法設(shè)計(jì)與分析】動(dòng)態(tài)規(guī)劃-練習(xí)題

    輸入一個(gè)整數(shù)數(shù)組 S[n] ,計(jì)算其最長遞增子序列的長度,及其最長遞增子序列。 定義 k ( 1 ≤ k ≤ n ) k (1 ≤ k ≤ n) k ( 1 ≤ k ≤ n ) ,L[k]表示以 S[k] 結(jié)尾的遞增子序列的最大長度。子問題即為 L[k]。 對(duì)于每一個(gè)k,我們都遍歷前面0~k-1的所有的數(shù),找出最大的L[i],且 S [ k ] L [

    2024年02月03日
    瀏覽(27)
  • 數(shù)據(jù)結(jié)構(gòu)與算法系列之習(xí)題練習(xí)

    數(shù)據(jù)結(jié)構(gòu)與算法系列之習(xí)題練習(xí)

    ?? ?? 博客:小怡同學(xué) ?? ?? 個(gè)人簡介:編程小萌新 ?? ?? 如果博客對(duì)大家有用的話,請(qǐng)點(diǎn)贊關(guān)注再收藏 ?? 括號(hào)匹配問題。 用隊(duì)列實(shí)現(xiàn)棧。 用棧實(shí)現(xiàn)隊(duì)列。 設(shè)計(jì)循環(huán)隊(duì)列。 有效的括號(hào) //用棧來實(shí)現(xiàn) //左括號(hào)進(jìn)棧 右括號(hào)出棧并銷毀如果不匹配則return //設(shè)置兩個(gè)隊(duì)列,入棧

    2024年02月11日
    瀏覽(25)
  • 數(shù)據(jù)結(jié)構(gòu)與算法--圖(概念+練習(xí)題+解析)

    數(shù)據(jù)結(jié)構(gòu)與算法--圖(概念+練習(xí)題+解析)

    有向圖 在有向圖中有以下幾點(diǎn)結(jié)論: 1.所有頂點(diǎn)的度數(shù)之和等于邊數(shù)的二倍。 2.所有頂點(diǎn)的入度之和等于出度之和。 3.n個(gè)頂點(diǎn)的有向完全圖有n(n-1)條邊。 4.n個(gè)頂點(diǎn)的強(qiáng)連通圖至少有n條邊。 無向圖 在無向圖中有以下幾點(diǎn)結(jié)論: 1.所有頂點(diǎn)的度數(shù)之和等于邊數(shù)的二倍。 2.n個(gè)頂

    2024年02月04日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包