【面試高頻題】值得仔細推敲的貪心及其證明

## 題目描述 這是 LeetCode 上的 **[1846. 減小和重新排列數(shù)組后的最大元素](https://leetcode-cn.com/problems/maximum-element-after-decreasing-and-rearranging/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-yh9qt/)** 术羔,難度為 **中等**赢赊。 Tag : 「貪心」 給你一個正整數(shù)數(shù)組?`arr`。 請你對 `arr`?執(zhí)行一些操作(也可以不進行任何操作)级历,使得數(shù)組滿足以下條件: 1. `arr`?中 第一個?元素必須為?$1$ 2. 任意相鄰兩個元素的差的絕對值小于等于?$1$ 對于任意的 $1 <= i < arr.length$?释移,都滿足?`abs(arr[i]-arr[i-1])<=1`,`abs(x)`?為?`x`?的絕對值寥殖。 你可以執(zhí)行以下 $2$ 種操作任意次: * 減小 `arr` 中任意元素的值玩讳,使其變?yōu)橐粋€更小的正整數(shù) * 重新排列?`arr`?中的元素,你可以以任意順序重新排列 請你返回執(zhí)行以上操作后嚼贡,在滿足前文所述的條件下熏纯,`arr`?中可能的最大值。 示例 1: ``` 輸入:arr = [2,2,1,2,1] 輸出:2 解釋: 我們可以重新排列 arr 得到 [1,2,2,2,1] 粤策,該數(shù)組滿足所有條件樟澜。 arr 中最大元素為 2 。 ``` 示例 2: ``` 輸入:arr = [100,1,1000] 輸出:3 解釋: 一個可行的方案如下: 1. 重新排列 arr 得到 [1,100,1000] 叮盘。 2. 將第二個元素減小為 2 秩贰。 3. 將第三個元素減小為 3 。 現(xiàn)在 arr = [1,2,3] 柔吼,滿足所有條件萍膛。 arr 中最大元素為 3 。 ``` 示例 3: ``` 輸入:arr = [1,2,3,4,5] 輸出:5 解釋:數(shù)組已經(jīng)滿足所有條件嚷堡,最大元素為 5 蝗罗。 ``` 提示: * $1 <= arr.length <= 10^5$ * $1 <= arr[i] <= 10^9$ ## 基本分析 & 證明 根據(jù)題意艇棕,數(shù)組的第一位必須是 $1$,且每個數(shù)只能 **減小** 或 **不變**串塑,數(shù)值位置可以任意調(diào)整沼琉。 求解經(jīng)過調(diào)整后,符合要求的數(shù)組中的最大值是多少桩匪。 首先符合條件的數(shù)組相鄰位差值絕對值不超過 $1$打瘪,這限定了數(shù)組的必然是如下三種分布之一: * (非嚴格)單調(diào)遞減 * 存在波段 * (非嚴格)單調(diào)遞增 *證明一:取得最優(yōu)解對應的數(shù)組「必然是」或者「可調(diào)整為」(非嚴格)單調(diào)遞增的形式。* 我們使用反證法來證明另外兩種分布不能取得最優(yōu)解: * (非嚴格)單調(diào)遞減:題目限定了數(shù)的范圍為正整數(shù)傻昙,且第一位為 $1$闺骚,這種情況不用討論了,跳過妆档; * 存在波段:我們始終可以將波峰的右側(cè)出現(xiàn)的值僻爽,納入到波峰的左側(cè),從而消掉這個波峰贾惦,最終將整個分布調(diào)整為「(非嚴格)單調(diào)遞增」的形式胸梆,結(jié)果不會變差: ![](https://upload-images.jianshu.io/upload_images/1980848-eb70ab40fb4acfd5.png) 多個波段的情況也是同理,可以自己在紙上畫畫须板。 都是利用 *波峰右側(cè)的點可以調(diào)整成波峰左側(cè)的點碰镜,從而使分布變?yōu)椋ǚ菄栏瘢﹩握{(diào)遞增*。 *至此习瑰,我們證明了最優(yōu)解對應的數(shù)組必然符合(非嚴格)單調(diào)遞增绪颖。* 這啟發(fā)我們可以先對原數(shù)組排個序,在此基礎上進行分析甜奄。 對原數(shù)組排序得到的有序數(shù)組菠发,不一定是符合「相鄰位差值絕對值不超過 $1$」的,同時由于每個數(shù)值可以選擇 **減小** 或 **不變**贺嫂。 *證明二:當必須要對當前位進行調(diào)整的時滓鸠,優(yōu)先選擇調(diào)整為「與前一值差值為 $1$ 的較大數(shù)」不會比調(diào)整為「與前一差值為 $0$ 的較小數(shù)」更差。* 這可以使用歸納推理第喳,假設采取「優(yōu)先調(diào)整為與前一值差值為 $1$ 的較大數(shù)」得到的序列為 `a`糜俗,采用「優(yōu)先調(diào)整與前一差值為 $0$ 的較小數(shù)」得到的序列為 `b`。 *根據(jù)「$a[0] = b[0] = 1$」曲饱、「`a` 和 `b` 長度一致」悠抹、「`a` 和 `b` 均為(非嚴格)單調(diào)遞增」以及「`a` 和 `b` 均滿足相鄰位差值不超過 $1$」,可推導出 $sum(a) >= sum(b)$扩淀,和任意位置 $a[i] >= b[i]$楔敌,從而推導出 `a` 序列的最后一位必然大于等于 `b` 的最后一位。* 即 `b` 不會比 `a` 更優(yōu)驻谆。 *證明三:調(diào)整大小的操作不會改變數(shù)組元素之間的相對位置關系卵凑。* 在證明二的分析中庆聘,我們會對某些元素進行“減小”操作,使得整個數(shù)組最終滿足「相鄰位差值絕對值不超過 $1$」勺卢。 但該證明成立的還有一個很重要的前提條件伙判,就是調(diào)整操作不會出發(fā)元素的位置重排。 那么該前提條件是否必然成立呢黑忱?答案是必然成立宴抚。 假設原排序數(shù)組中存在需要調(diào)整的點 $i$ 和點 $j$,且 $nums[i] <= nums[j]$甫煞。 為了讓數(shù)組滿足條件菇曲,它們都進行了“減少”操作的調(diào)整,分別變?yōu)榱?$p$ 和 $q$抚吠,如果觸發(fā)位置重排的話常潮,必然有 $nums[p] >= nums[q]$。 此時埃跷,我們能夠通過調(diào)整它們的變化關系:點 $i$ 變?yōu)辄c $q$蕊玷、點 $j$ 變成點 $p$ 來確保同樣滿足條件邮利,且不觸發(fā)元素在有序數(shù)組中的位置重排弥雹。 ![](https://upload-images.jianshu.io/upload_images/1980848-38637e31c6a6a119.png) ## 貪心 排序,限定第一位值為 $1$延届,從前往后處理剪勿,根據(jù)每一位是否「必須修改(與上一位差值是否大于 $1$)」做決策,如果必須被修改方庭,則修改為與前一值差值為 $1$ 的較大數(shù)厕吉。 代碼: ```Java class Solution { public int maximumElementAfterDecrementingAndRearranging(int[] arr) { int n = arr.length; Arrays.sort(arr); arr[0] = 1; for (int i = 1; i < n; i++) { if (arr[i] - arr[i - 1] > 1) { arr[i] = arr[i - 1] + 1; } } return arr[n - 1]; } } ``` * 時間復雜度:假定 `Arrays.sort` 使用的是雙軸快排實現(xiàn)。復雜度為 $O(n\log{n})$ * 空間復雜度:假定 `Arrays.sort` 使用的是雙軸快排實現(xiàn)械念。復雜度為 $O(\log{n})$ ## 最后 這是我們「刷穿 LeetCode」系列文章的第 `No.1846` 篇头朱,系列開始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道題目龄减,部分是有鎖題项钮,我們將先把所有不帶鎖的題目刷完。 在這個系列文章里面希停,除了講解解題思路以外烁巫,還會盡可能給出最為簡潔的代碼。如果涉及通解還會相應的代碼模板宠能。 為了方便各位同學能夠電腦上進行調(diào)試和提交代碼亚隙,我建立了相關的倉庫:https://github.com/SharingSource/LogicStack-LeetCode 。 在倉庫地址里违崇,你可以看到系列文章的題解鏈接阿弃、系列文章的相應代碼诊霹、LeetCode 原題鏈接和其他優(yōu)選題解。 更多更全更熱門的「筆試/面試」相關資料可訪問排版精美的 [合集新基地](https://www.acoier.com/archives/) ???? 本文由[mdnice](https://mdnice.com/?platform=6)多平臺發(fā)布
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恤浪,一起剝皮案震驚了整個濱河市畅哑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌水由,老刑警劉巖荠呐,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異砂客,居然都是意外死亡泥张,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門鞠值,熙熙樓的掌柜王于貴愁眉苦臉地迎上來媚创,“玉大人,你說我怎么就攤上這事彤恶〕疲” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵声离,是天一觀的道長芒炼。 經(jīng)常有香客問我,道長术徊,這世上最難降的妖魔是什么本刽? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮赠涮,結(jié)果婚禮上子寓,老公的妹妹穿的比我還像新娘。我一直安慰自己笋除,他們只是感情好斜友,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垃它,像睡著了一般鲜屏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗤瞎,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天墙歪,我揣著相機與錄音,去河邊找鬼贝奇。 笑死虹菲,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的掉瞳。 我是一名探鬼主播毕源,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼浪漠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霎褐?” 一聲冷哼從身側(cè)響起址愿,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冻璃,沒想到半個月后响谓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡省艳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年娘纷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跋炕。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡赖晶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辐烂,到底是詐尸還是另有隱情遏插,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布纠修,位于F島的核電站胳嘲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏分瘾。R本人自食惡果不足惜胎围,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一吁系、第九天 我趴在偏房一處隱蔽的房頂上張望德召。 院中可真熱鬧,春花似錦汽纤、人聲如沸上岗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肴掷。三九已至,卻和暖如春背传,著一層夾襖步出監(jiān)牢的瞬間呆瞻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工径玖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留痴脾,地道東北人。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓梳星,卻偏偏與公主長得像赞赖,于是被迫代替她去往敵國和親滚朵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容