LeetCode算法題:11. 盛最多水的容器(Java)(雙指針問題總結)

給定一個長度為 n 的整數數組 height 。有 n 條垂線,第 i 條線的兩個端點是 (i, 0)(i, height[i])

找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。

返回容器可以儲存的最大水量。

在這里插入圖片描述

提示:

  • n == height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

解題思路:

定義兩個指針啊a,b分別指向height數組的第一個元素和第二個元素,表示容器的左邊和容器右邊,定義一個maxVolume表示記錄的最大容量,初始定義為0。定義兩層循環,外層循環a指針,內層循環b指針,如果當a,b指針所形成容器的容量大于maxVolume時更新maxVolume。遍歷完之后找到最大值。

class Solution {public int maxArea(int[] height) {int maxVolume = 0;for(int a=0;a<height.length;a++){for(int b=a+1;b<height.length;b++){if(((b-a)*Math.min(height[a],height[b]))>maxVolume)maxVolume = (b-a)*Math.min(height[a],height[b]);}}return maxVolume;}
}

時間復雜度為O(n^2),空間復雜度為O(1)。提交報錯:
在這里插入圖片描述
時間復雜度過高,得想辦法降低時間復雜度。

修改思路:

初始化定義兩個指針a,b分別指向height數組第一個元素和最后一個元素。初始化maxVolume等于height[a]*height[b]表示當前最大容量,分析一下可以知道,當前狀態的容量底寬是最寬的情況了,那么容量的大小,取決于左邊和后邊較矮的邊。例如如果當前是a,b所指高度是a所指高度較矮,那么要做到下一次找到的容器比原來的大,只能是找到一個更高的左邊才有可能。同理,如果是右邊更矮,則要找到一個更高的右邊才行。因此每次移動較矮的那一邊,如果是左邊更矮,則向右移,找到一個比原來左邊高的邊,重新計算容量;如果是右邊更矮,則向左移,找到一個比原來右邊高的邊。重新計算容量,如果比之前容量大,則更新maxVolume。直到左邊指針越過右邊指針,則停下。當前maxVolume是最大的容量。

代碼:

class Solution {public int maxArea(int[] height) {int a=0,b=height.length-1;int maxVolume=(b-a)*(Math.min(height[a],height[b]));int maxLeftEdge = height[a],maxRightEdge = height[b];while(a<b){if(height[a]<height[b]){a = a+1;while(height[a]<=maxLeftEdge&&a<b)a=a+1;}else{b = b-1;while(height[b]<=maxRightEdge&&a<b)b=b-1;}if((b-a)*(Math.min(height[a],height[b]))>maxVolume){maxVolume = (b-a)*(Math.min(height[a],height[b]));maxLeftEdge = height[a];maxRightEdge = height[b];}}return maxVolume;}
}

結果:

在這里插入圖片描述

上述算法時間復雜度為O(n),空間復雜度為O(1)。
但是看到時間復雜度依然有改進空間。查看1ms時間復雜度的代碼:

class Solution {public int maxArea(int[] height) {int l =0,r =height.length-1;int max =0;while(l<r){if(height[r]>height[l]){max = Math.max(max,(r-l)*height[l]);int tmp = height[l];while(tmp>= height[l]&&l<r) l++;}else{max = Math.max(max,(r-l)*height[r]);int tmp = height[r];while(tmp>= height[r]&&l<r) r--;}}return max;}
}

觀察發現,總體代碼邏輯與我自己的一樣,不同點在于每次的maxVolume計算使用了Math.max(max,(r-l)*height[l]),同時是放在if語句中計算。同時只是使用一個臨時變量存儲之前左右邊高度。避免了重復的矮邊判斷。

總結

雙指針問題,較低時間復雜度解題的關鍵在于如何初始化指針位置以及找到如何移動指針的策略。例如這一題在于初始化指針為第一個元素和最后一個元素,同時分別找到最矮邊移動以計算最大值。我文章中的前一題,移動零問題,在于初始化指針都為數組開頭,然后移動一個指針尋找非零0,另一個指針定位下一個非零值存放的位置。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/12747.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/12747.shtml
英文地址,請注明出處:http://en.pswp.cn/web/12747.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

第十四屆藍橋杯大賽軟件賽國賽C/C++ 大學 B 組 數三角

//枚舉頂點。 //不存在等邊三角形 #include<bits/stdc.h> using namespace std; #define int long long const int n2e311; int a,b,c,l[n],r[n]; signed main() {ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>a;for(int i1;i<a;i){cin>>…

UE4_環境_局部霧化效果

學習筆記&#xff0c;不喜勿噴&#xff01;侵權立刪&#xff01;祝愿大家生活越來越好&#xff01; 本文重點介紹下材質節點SphereMask節點在體積霧中的使用方法。 一、球體遮罩SphereMask材質節點介紹&#xff1a; 球體蒙版&#xff08;SphereMask&#xff09; 表達式根據距…

【筆記】Android Studio 版本信息

Android Studio Jellyfish | 2023.3.1 | Android Developers Android Studio 是開發 Android 應用的官方 IDE&#xff0c;包含構建 Android 應用所需的所有功能。 AS與AGP版本適用關系 AGP(Android Gradle plugin) Android gradle插件 Androdi Studio versionRequired AG…

2024紅帽全球峰會:CEO行業洞察分享

作為全球IT領域一年一度的行業盛宴&#xff0c;2024紅帽全球峰會于近日盛大召開。生成式AI與大模型是當前IT行業最受關注的熱點話題&#xff0c;而紅帽在生成式AI與大模型領域的最新動作&#xff0c;也理所當然地成為了本屆峰會觀眾目光聚集的焦點。 作為世界領先的開源解決方案…

使用vcpkg與json文件自動安裝項目依賴庫

說明 本文記錄自己使用vcpkg.json文件自動安裝依賴庫并完成編譯的全過程。 關于vcpkg是什么這里就不多詳細解釋&#xff0c;可以看一下專門的介紹及安裝的文章&#xff0c;總之了解這是一個C的包管理工具就可以了。 流程 下面介紹從GitHub上克隆C項目以及為這個項目安裝所需…

二叉樹的常見操作

建立樹 復制二叉樹 計算深度 計算總結點數 計算葉子結點數

OpenHarmony標準設備應用開發(二)——布局、動畫與音樂

本章是 OpenHarmony 標準設備應用開發的第二篇文章。我們通過知識體系新開發的幾個基于 OpenHarmony3.1 Beta 標準系統的樣例&#xff1a;分布式音樂播放、傳炸彈、購物車等樣例&#xff0c;分別介紹下音樂播放、顯示動畫、動畫轉場&#xff08;頁面間轉場&#xff09;三個進階…

AI工具的熱門與卓越:揭示AI技術的實際應用和影響

文章目錄 每日一句正能量前言常用AI工具創新AI應用個人體驗分享后記 每日一句正能量 我們在我們的勞動過程中學習思考&#xff0c;勞動的結果&#xff0c;我們認識了世界的奧妙&#xff0c;于是我們就真正來改變生活了。 前言 隨著人工智能&#xff08;AI&#xff09;技術的快…

深度剖析MyBatis的二級緩存

二級緩存的原理 MyBatis 二級緩存的原理是什么&#xff1f; 二級緩存的原理和一級緩存一樣&#xff0c;第一次查詢會將數據放到 緩存 中&#xff0c;然后第二次查詢直接去緩存讀取。但是一級緩存是基于 SqlSession 的&#xff0c;二級緩存是基于 mapper 的 namespace 的。也就是…

關于API接口的自述

在實際工作中&#xff0c;我們需要經常跟第三方平臺打交道&#xff0c;可能會對接第三方平臺API接口&#xff0c;或者提供API接口給第三方平臺調用。 那么問題來了&#xff0c;如果設計一個優雅的API接口&#xff0c;能夠滿足&#xff1a;安全性、可重復調用、穩定性、好定位問…

Qt運行時,如何設置第一個聚焦的控件

問題&#xff1a;Qt第一個聚焦的控件&#xff0c;如何自行設置&#xff1f; 嘗試&#xff1a; 1.在代碼中設置 lineEdit->setFocus() 。無效&#xff01; 2.Qt Designer–打開form1.ui–菜單欄下一行–Edit Tab Order–按順序點擊–菜單欄下一行–Edit Widgets–退出。無效…

為什么做了功能測試還要做接口測試

接口測試與功能測試不是重復的測試,而是互為補充的測試策略。 在軟件測試領域,接口測試和功能測試被視為質量保證過程中至關重要的組成部分。盡管它們之間存在部分重復,但更多的情況下,它們相輔相成,各自發揮著獨特的作用。本文將探討接口測試與功能測試之間的關系,以及它…

【easyX】動手輕松掌握easyX 1

01 簡單繪圖 在這個程序中&#xff0c;我們先初始化繪圖窗口。其次&#xff0c;簡單繪制兩條線。 #include <graphics.h>//繪圖庫頭文件 #include <stdio.h> int main() {initgraph(640, 480);//初始化640?480繪圖屏幕line(200, 240, 440, 240);//畫線(200,240)…

MySQL是如何選擇索引的?

2.3.5. 索引選擇 MySQL是如何選擇索引的&#xff1f; 優化器決定了具體某一索引的選擇&#xff0c;也就是常說的執行計劃。而優化器的選擇是基于成本&#xff08;cost&#xff09;&#xff0c;哪個索引的成本越低&#xff0c;優先使用哪個索引。 SQL 優化器會分析所有可能的執…

Python操作鼠標鍵盤和爬蟲

一.pyautogui 庫 pyautogui 是一個 Python 庫&#xff0c;允許控制鼠標和鍵盤。可以通過它編寫 Python 腳本來自動執行各種任務&#xff0c;例如點擊按鈕、輸入文本、移動鼠標等。這個庫非常適合用來編寫自動化腳本來完成重復性的工作&#xff0c;比如網頁表單填寫、屏幕截圖、…

STC8增強型單片機開發——定時器Timer

一、定時器 定時器是一種計時裝置&#xff0c;通常由一個晶體振蕩器提供時鐘信號&#xff0c;可以計時一定的時間后執行相應的操作。在單片機中&#xff0c;定時器一般是由計數器和時鐘源組成的&#xff0c;可以用來產生一定時間間隔的中斷信號&#xff0c;或者用于測量輸入信號…

開放式運動耳機哪款好用?五款高性能值得信賴產品推薦

身為戶外運動的達人&#xff0c;我發現開放式運動耳機簡直是咱們運動時的最佳拍檔&#xff0c;不管是跑步還是健身&#xff0c;開放式運動耳機最為舒適&#xff0c;它的妙處就在于不用塞進耳朵&#xff0c;這樣既安全又衛生&#xff0c;戶外動起來更放心。但市面上好壞參半&…

AIGC行業:探索發展風口,把握市場脈搏

AIGC行業現在適合進入嗎 簡介&#xff1a; AIGC行業&#xff1a;探索發展風口&#xff0c;把握市場脈搏 隨著人工智能技術的快速發展&#xff0c;AIGC&#xff08;人工智能生成內容&#xff09;行業正逐漸成為科技界的新寵。在當前的時代背景下&#xff0c;我們不禁要問&…

Chisel中對對<: 和:的理解(其實是Scala中的理解)

在 Scala 語言和 Chisel 硬件構造語言中&#xff0c;<: 和 : 是用于類型注解的兩個不同的符號&#xff0c;它們在泛型編程和類型系統中扮演重要角色。下面是它們各自的意義和用途&#xff1a; <:&#xff08;子類型關系&#xff09; <: 符號在 Scala 中表示子類型關…

Nginx詳細介紹一

Nginx是一個高性能的HTTP和反向代理服務器&#xff0c;它也可以作為郵件服務器使用。 Nginx基本介紹 基本概念&#xff1a; Nginx可以處理大量的并發連接&#xff0c;具有很高的穩定性和低資源消耗的特點。它主要用于Web服務、反向代理、負載均衡和HTTP緩存等場景。 安裝與配…