主頁 > 移動端開發 > 在陣列中查找兩個數字,使得它們之間的所有元素都小于兩個數字中的最小值

在陣列中查找兩個數字,使得它們之間的所有元素都小于兩個數字中的最小值

2021-10-14 14:44:38 移動端開發

如何在陣列中找到對,使得它們之間的元素小于對中的最小元素。

例如。
10 4 6 8 7

在上面的對中可以形成如下:
(10,4), (4,6), (6,8), (8,7)因為它們之間沒有元素所以它也有效
(10,6) As only它們之間的元素是44 < 6這是最小的 10,6
(10, 8) * As 4 < 8 and also 6 < 8 *

但 (10,7)不會成對為8 > 7

所有對:

(10, 4), (4, 6), (6, 8), (8, 7), (10, 6), (10, 8)

我的代碼:

def findPirs(n, values):
    res = 0
    arr = []
    for start in range(n-1):
        currMax = 0
        for end in range(start 1, n):
            m = min(values[start], values[end])
            if currMax < m:
                arr.append((values[start], values[end]))
                res  = 1
            currMax = max(currMax, values[end])

    return res, arr

這是我當前的代碼,它有效 效率非常低,因為它的時間復雜度O(n^2)
關于如何改進的任何建議?

uj5u.com熱心網友回復:

你不需要最低限度。如果新端點大于您迄今為止檢測到的最大值,那么您就獲勝了。

def findPairs(values):
    arr = []
    for start in range(len(values)-1):
        currMax = 0
        for end in values[start 1:]:
            if end > currMax:
                arr.append((values[start], end))
                currMax =  end
    return arr

nums = [10, 4, 6, 8, 7]
print(findPairs( nums ))

uj5u.com熱心網友回復:

我在上面的評論中對我暗示的解決方案進行了更多思考,我認為它可以作業。在最壞的情況下,您永遠不會比 O(n2) 更好,因為您可能必須輸出 O(n2) 對,但我們的想法是,當您不必輸出太多時,您可能希望擁有一種快速的演算法,然后(必然)在有很多輸出時變慢。O(n z) 演算法,其中 z 是輸出的大小,最適合需要查看所有資料并且需要輸出所有對的情況。

所以,我的解決方案,如下所示。如果輸出很大,它就無法與快速 O(n2) 解決方案競爭——它有更多的開銷——但是當你輸出 o(n2) 時它應該可以正常作業。

這個想法僅適用于超過兩個的間隔,所以我將所有鄰居視為我剛剛報告的特例。我可以在 O(n) 中輕松做到這一點。對于更長的時間間隔,我認為輸入是一系列山丘和山谷,山頂位于位置 i,其中 x[i-1] < x[i] 和 x[i] < x[i 1]。我不知道您想如何處理運行相同值的情況,但您可以調整代碼來處理它。這僅取決于您想對它們做什么。

如果我有兩個相鄰的山頂,它們之間有一個山谷,我必須報告兩邊的間隔。在山谷中間會有一些我不能使用的值,最初它是一個區間中的最小值(不能包括在內),后來我屏蔽了更大的塊,把小山丘變成了山谷。

因此,總的來說,我采用成對的相鄰山頂,在它們之間的山坡上輸出間隔。

def report_valid_intervals(x: list[int]):
    """Report intervals (i,j) such that for all i <= k < j, x[k] <= min(x[i],x[j])."""

    # All neighbours are valid, and these are a special case that we handle first.
    for i in range(len(x) - 1):
        yield i, i 1

    # Identify hills and valleys in the sequence. These are the valleys we use
    # to report intervals where the left and right points are larger than the
    # interval values. Identifying the hill tops (tops) and valleys (masks)
    # is done in O(n).
    masks = [False] * len(x)
    tops = find_tops(x, masks)

    # Now process valleys one by one. In each valley, we report the intervals inside it
    # in O(z) -- linear in what we report -- and then we update the mask, throwing
    # away one hill top (making it into a valley) for each pair, also in O(z) (we
    # only look at indices we also used in the output). When we are through all the
    # valleys we have elimiated at least half of them. Because we eliminate half each
    # time, the running time (excluding reporting) is the sum n   n/2   n/4   ... a
    # geomemtric sum that converges to O(n).
    while len(tops) > 1:
        for left, right in zip(tops, tops[1:]):
            for i, j in report_intervals_in_valley(x, left, right, masks):
                yield i, j
            update_valley_mask(x, left, right, masks)

        # eliminate the smaller tops
        tops = [top for top in tops if not masks[top]]

您可以像這樣輕松識別山丘和山谷(但您可能希望重新定義頂部以處理具有相同值的運行的情況)。

# Identifying hills and valleys...
def find_tops(x: list[int], masks: list[bool]) -> list[int]:
    """Locate the tops of the hills and mask out the bottom of the valleys.
    Runs in O(n) and only runs once."""
    # Get hill tops
    start = [0] if x[0] > x[1] else []
    end = [len(x)-1] if x[-1] > x[-2] else []
    mid = [i for i in range(1, len(x)-1) if x[i-1] < x[i] > x[i 1]]
    tops = start   mid   end

    # mask valley bottoms. Doesn't matter with the end-points,
    # since they are only relevant as tops.
    for i in range(1, len(x)-1):
        if x[i-1] > x[i] < x[i 1]:
            masks[i] = True

    return tops

迭代地穿過相鄰的山頂是線性時間,因為我們每次消除一半的山頂,得到一個幾何和。如果我們更多地分析底層運行時間,我不確定這里是否需要論證,但如果我們需要它,它就在那里。我們只需要按與我們從中獲得的輸出成比例的時間處理每個谷。在這里它變得有點棘手。

You can output intervals in a valley by running down one side, and then running down the other side as long as you do not include a value smaller than the next value on the first side. If you output something every time you do this, you get O(z), but you could run down a side and test the first value on the other side repeatedly, without outputting anything. Then you spend O(m) time, where m is the length of the side of the valley, and then the running time goes above O(n z).

However, we are going to mask out indices that cannot be used after we have processed a valley. All indices with a value smaller than the smallest peak cannot be part of an interval that spans across a hill top, and we can mask those out so we do not consider them. If we process valleys such that we do the expensive work on the smaller hill, we will mask out the indices we process, and since they are only masked out once and then never considered again, we are back to O(n z).

# When reporting from a valley, work out the valid left and right interval to
# consider. Those are the indices from the left/right respectively until we see a
# masked index. The masked indices are valleys that we have already processed,
# and we do not need to consider anything in there, as intervals spanning them
# must also contain values that are too large for a hill top inbetween.


def report_intervals_in_valley_left(x: list[int],
                                    left_top: int, right_top: int,
                                    masks: list[bool]):
    """Report all valid intervals in a valley. The running time is O(lv z) where
    z is the number of intervals we report and lv is the size of the left side
    of the valley (because we look at all those indices even if we do not
    report). We will mask out those intervals afterward so we never look at
    them again, so they cannot contribute more than O(n) to the algorithm in
    total."""
    for i in range(left_top, right_top):
        if masks[i]:  # end of this side of the valley
            break
        for j in range(right_top, left_top, -1):
            if masks[j]:
                break
            if x[j] < x[i   1]:  # we cannot go below the next on the other side
                break  # no more hits from i
            yield i, j


def report_intervals_in_valley_right(x: list[int],
                                     left_top: int, right_top: int,
                                     masks: list[bool]):
    """Report all valid intervals in a valley. The running time is O(rv z) where
    z is the number of intervals we report and rv is the size of the right side
    of the valley (because we look at all those indices even if we do not
    report). We will mask out those intervals afterward so we never look at
    them again, so they cannot contribute more than O(n) to the algorithm in
    total."""
    for j in range(right_top, left_top, -1):
        if masks[j]:
            break
        for i in range(left_top, right_top):
            if masks[i]:  # end of this side of the valley
                break
            if x[i] < x[j - 1]:  # we cannot go below the next on the other side
                break  # no more hits from i
            yield i, j


def report_intervals_in_valley(x: list[int],
                               left_top: int, right_top: int,
                               masks: list[bool]):
    """Report all valid intervals in a valley. The running time is O(v z) where
    z is the number of intervals we report and v is the size of the side of the
    valley that will be masked out and not contribute to the running time again."""
    # make sure it is the side with the smallest top that risks doing
    # the most work
    if x[left_top] < x[right_top]:
        yield from report_intervals_in_valley_left(x, left_top, right_top, masks)
    else:
        yield from report_intervals_in_valley_right(x, left_top, right_top, masks)

When you update a valley by masking, you remove the values smaller than the smallest peak. Here, my current code doesn't quite do the right thing.

def update_valley_mask(x: list[int],
                       left_top: int, right_top: int,
                       masks: list[bool]):
    """Mask out the indices that are smaller than the smallest top. Those cannot
    be part of valid pairs when we merge this valey with its neighbours. The running
    time is less than the time we spent reporting intervals, since each index we
    consider was part of at least one pair that we outputted."""
    mi = min(x[left_top], x[right_top])
    masks[left_top if x[left_top] == mi else right_top] = True

    for i in range(left_top, right_top):  # range is entire interval, but we break
        if masks[i]:
            break  # we enter the already masked, so get out to get the correct running time
        if x[i] < mi:
            masks[i] = True
    for i in range(right_top, left_top, -1):
        if masks[i]:
            break
        if x[i] < mi:
            masks[i] = True

The code processes the sides of the valley, and it looks at indices that do not get masked out. That means that it doesn't guarantee the O(n z) running time. However, it should be simple enough to keep track of the closest masked index on the left and right of each hill top. We know the tops of our valley when we mask, so it would just be updating a list. If we do that, then we can start from the closest masked value and work our way up towards the hill top, and then we will mask all the indices we process exact the last, and then the running time is correct again.

I can have a go at it, but I suspect this is only of theoretical interest. The O(n2) solutions are probably fast enough for most cases (and if you have to output many intervals you cannot do better). But I'm reasonably sure that you can do it in O(n z), and probably smarter than this solution.

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/312889.html

標籤:Python 数学 数据结构

上一篇:廣義關聯勒讓德多項式

下一篇:將雙數轉換為數字,反之亦然?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more