C++算法 —— 貪心(3)

文章目錄

  • 1、買賣股票的最佳時機
  • 2、買賣股票的最佳時機Ⅱ
  • 3、K次取反后最大化的數組和
  • 4、按身高排序
  • 5、優勢洗牌
  • 6、最長回文串
  • 7、增減字符串匹配


1、買賣股票的最佳時機

121. 買賣股票的最佳時機

在這里插入圖片描述
這里最容易想到的就是暴力枚舉,兩層for循環,i = 0, j = i + 1開始,但是這樣是O(n ^ 2)的時間復雜度,即使倒過來,選定一個值,找到這個值前面的一堆數字中的最小值,一減就能找到最大利潤,但是沒解決本質。不妨想一下,從第二個數開始往后走。每一次都找前面一堆數字的最小值,但后面要找的其實已經包含前面要找的了,也就是找第7個數字之前的最小值,一大部分已經在找第6個數字之前的最小值時找過了,只要把這個最小值和第6個數字一比較,誰小,誰就是找第7個數字之前的最小值,這樣,算法就是O(N)了。

    int maxProfit(vector<int>& prices) {int res = 0;for(int i = 0, prev = INT_MAX; i < prices.size(); ++i){res = max(res, prices[i] - prev);//先更新結果是因為如果先更新最小值,那么結果就沒法計算了prev = min(prev, prices[i]);}return res;}

2、買賣股票的最佳時機Ⅱ

122. 買賣股票的最佳時機 II

在這里插入圖片描述
根據這個圖,可以畫一個折線圖,每天的價格就是一個點,連接起來所有點。思路就是每次選一個點,都找到從這個點開始持續遞增后的點,如果價格出現減少或不變,那就停止,這樣每個增長趨勢內可得到的最大利潤都被算進來了,就能得到最大利潤。

為了找到嚴格遞增過程中最大的點,可以用雙指針來控制。另一個方法是把每段交易變成一天一天,這個思路是只要第二天的數字比第一天大,那就加上第二天的數字。

        //雙指針int ret = 0, n = prices.size();for(int i = 0; i < n; ++i){int j = i;while(j + 1 < n && prices[j + 1] > prices[j]) ++j;ret += prices[j] - prices[i];i = j;}return ret;//拆分int ret = 0;for(int i = 1; i < prices.size(); ++i){if(prices[i] > prices[i - 1])ret += prices[i] - prices[i - 1];}return ret;

3、K次取反后最大化的數組和

1005. K 次取反后最大化的數組和

在這里插入圖片描述
理解這道題后會發現,應當先對最小的負數取反,才能得到最大和。從負數開始,從小到大,一個個取反。假設m是負數個數,m > k,那就把前k小的負數轉化成正數;m == k,把所有負數全部轉化為正數;m < k,先把所有負數都取反,剩余的次數k - m,如果它是偶數,那么就無影響,可以只對一個數字取反偶次數,那么這個數不變,如果是k - m是奇數,那就得把現有正數(因為已經取反了所有負數)中最小的那個數取反奇次數,就可以拿到最大數組和了。

    int largestSumAfterKNegations(vector<int>& nums, int k) {int m = 0, minElem = INT_MAX, n = nums.size();for(auto x : nums){if(x < 0) m++;minElem = min(minElem, abs(x));}int ret = 0;if(m > k){sort(nums.begin(), nums.end());for(int i = 0; i < k; ++i){ret += -nums[i];}for(int i = k; i < n; ++i){ret += nums[i];}}else{for(auto x: nums) ret += abs(x);if((k - m) % 2){ret -= minElem * 2;}}return ret;}

4、按身高排序

2418. 按身高排序

在這里插入圖片描述
我們可以創建一個新數組pair<int, string>這樣名字和數字都在一起,對這個數組排序就行。

解法二是利用哈希表存映射關系。對身高數組排序,根據結果在哈希表里找名字即可。

以上兩種思路類似,這里走一個不同的思路,雖然要排序,但不是真正的排序,對其中的元素不做手腳,但要能按照給出最終的順序對應的元素。這里創建一個下標數組,只對下標數組排序,根據下標數組排序后的結果,找到原數組的信息。

    vector<string> sortPeople(vector<string>& names, vector<int>& heights) {int n = names.size();vector<int> index(n);for(int i = 0; i < n; ++i){index[i] = i;}sort(index.begin(), index.end(), [&](int i, int j){return heights[i] > heights[j];});vector<string> ret;for(auto i : index){ret.push_back(names[i]);}return ret;}

5、優勢洗牌

870. 優勢洗牌

在這里插入圖片描述
這道題的意思是給了兩個數組,返回一個最終的數組,比如例1,
2 7 11 15
1 10 4 11
第一個位置可以放2,比1,第二個位置可以放11,比10大,第三個可以放15,比4大,但這樣第四個位置就放不了,所以這樣優勢不是最大化,第三個位置放7,第四個位置可以放15,這樣優勢就最大化了。

這道題可以用田忌賽馬的思路,即,如果比不過,就放到另一個數組最大的那個對應的位置,如果能比過,那就直接比。在這之前,先排序一遍。

按照這個思路,看例2,我們會得到[12, 24, 32, 8]這個答案,和示例不一樣,這是因為,我們是按照排序后的數組去做的結果,這個結果還需要對應上原先數組,所以還得改一下順序,才是最終結果。

為此,要和上一個題一樣,用下標數組來做。

    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {int n = nums1.size();//排序sort(nums1.begin(), nums1.end());vector<int> index2(n);for(int i = 0; i < n; ++i) index2[i] = i;sort(index2.begin(), index2.end(), [&](int i, int j){return nums2[i] < nums2[j];});//田忌賽馬vector<int> ret(n);int left = 0, right = n - 1;for(auto x : nums1){if(x > nums2[index2[left]]) ret[index2[left++]] = x;else ret[index2[right--]] = x;}return ret;}

6、最長回文串

409. 最長回文串

在這里插入圖片描述
按照題目,回文串的長度是偶數或者奇數,從中間切一刀,兩邊都一樣,中間切開的那個位置沒有元素或者只有一個元素。所以我們可以這樣想,一個字符串中可能出現的所有字符,記錄下每個字符出現的次數,如果次數為偶數,就可以兩邊都放,那就是直接加上這個數字;如果是奇數,就-1,然后兩邊都放。所有次數可能不止有一個奇數,但奇數的個數不用擔心,按照上面的做法,偶數就直接加,奇數就-1加上,算出來的長度如果等于原字符串長度,說明都是偶數,那就不用繼續處理,直接返回;如果小于原字符串,說明出現了奇數,那么就+1,再返回。

    int longestPalindrome(string s) {int hash[127] = {0};for(char ch : s) hash[ch]++;int ret = 0;for(int x : hash){ret += x / 2 * 2;//這樣奇數偶數都能計算}return ret < s.size() ? ret + 1 : ret;}

7、增減字符串匹配

942. 增減字符串匹配

在這里插入圖片描述
題目的意思就是給定一個字符串,比如IDI,那就增減增,從0123四個數字中選擇來組成數組。

這道題體現的貪心是,為了符合字符串展現的規則,遇到I時,應當選擇當前最小的那個數,遇到D時,選擇當前最大的那個數。

    vector<int> diStringMatch(string s) {int left = 0, right = s.size();vector<int> res;for(auto ch : s){if(ch == 'I') res.push_back(left++);else res.push_back(right--);}res.push_back(left);return res;}

結束。

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

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

相關文章

RTMP直播應用與延時分析

直播應用中&#xff0c;RTMP和HLS基本上可以覆蓋所有客戶端觀看&#xff0c; HLS主要是延時比較大&#xff0c;RTMP主要優勢在于延時低。 一、應用場景 低延時應用場景包括&#xff1a; . 互動式直播&#xff1a;譬如2013年大行其道的美女主播&#xff0c;游戲直播等等各種…

TFA-Net

TFA SCA means ‘Self-Context Aggregation’ 作者未提供代碼

一文講明Mybatis 的使用 超詳細 【爆肝兩萬字教程】

我 | 在這里 &#x1f575;? 讀書 | 長沙 ?軟件工程 ? 本科 &#x1f3e0; 工作 | 廣州 ? Java 全棧開發&#xff08;軟件工程師&#xff09; &#x1f383; 愛好 | 研究技術、旅游、閱讀、運動、喜歡流行歌曲 &#x1f3f7;? 標簽 | 男 自律狂人 目標明確 責任心強 ??公…

數據字典回顯功能設計與實現

數據字典回顯功能設計與實現 文章目錄 數據字典回顯功能設計與實現1. 業務場景2. 實現設計2.1 注解AOP切面2.2 注解mybatis攔截器2.3 注解序列化2.4 涉及字段直接申明成字典引用類型mybatis攔截器反序列化處理 3. 具體實現 1. 業務場景 我們日常開發中經常會遇到&#xff1a;數…

羊大師教你,什么搭配羊奶能夠帶來全方位的營養?

羊奶作為一種營養價值極高的乳制品&#xff0c;其豐富的營養成分對人體健康有著諸多益處。然而&#xff0c;不同的食物搭配會對羊奶的營養吸收產生不同的影響。為了讓大家更好地利用羊奶的營養價值&#xff0c;下面小編羊大師將為大家介紹一些與羊奶搭配的食物&#xff0c;幫助…

Qt實現畫的圖片移動

要實現左鍵點擊鼠標時圖片跟著鼠標移動&#xff0c;可以通過以下步驟來實現&#xff1a;1. 在QGraphicsView的構造函數中設置鼠標跟蹤屬性&#xff0c;以便能夠捕獲鼠標事件。cpp QGraphicsView::QGraphicsView(QWidget *parent) : QGraphicsView(parent) {setMouseTracking(tr…

Leetcode617合并二叉樹

理解題意&#xff1a;相同節點位置上&#xff0c;都有數據的話&#xff0c;節點值相加&#xff0c;只有一方有數據的話&#xff0c;把有數據的部分及相關子樹保留下來。 考察操作兩棵二叉樹&#xff0c;二叉樹的遍歷。 一般有兩種解決方式&#xff1a; 遞歸|迭代。 區別&#x…

element 中文地址

Element - The worlds most popular Vue UI framework 2 Menu 菜單 | Element Plus 3 偵聽器 | Vue.js vue中文官網

軟件測試職業規劃導圖

公司開發的產品專業性較強&#xff0c;軟件測試人員需要有很強的專業知識&#xff0c;現在軟件測試人員發展出現了一種測試管理者不愿意看到的景象&#xff1a; 1、開發技術較強的軟件測試人員轉向了軟件開發(非測試工具開發)&#xff1b; 2、業務能力較強的測試人員轉向了軟件…

ubuntu創建新用戶, 并賦予root權限

在Ubuntu上創建新用戶可以通過adduser命令來完成。以下是創建新用戶的基本步驟&#xff1a; 打開終端&#xff1a;你可以按下Ctrl Alt T來打開終端。 使用sudo命令以管理員權限執行adduser命令。例如&#xff0c;如果你要創建一個名為newuser的新用戶&#xff0c;運行以下命…

【EI會議征稿】第三屆電子信息技術國際學術會議(EIT 2024)

The 3rd International Conference on Electronic Information Technology 第三屆電子信息技術國際學術會議&#xff08;EIT 2024&#xff09; 電子信息工程在我國信息化產業的發展過程中舉足輕重&#xff0c;且隨著現代社會的發展&#xff0c;航空航天領域、制造業領域和智能…

LSTM+CNN實現時間序列預測(負荷預測)

文章目錄 LSTM+CNN實現時間序列預測(PyTorch版)基于PyTorch搭建LSTM+CNN模型實現風速時間序列預測配置類時序數據集的制作數據歸一化數據集加載器搭建LSTM+CNN模型定義模型、損失函數、優化器模型訓練可視化結果十、完整源碼LSTM+CNN實現時間序列預測(Keras版)源碼模型訓練繪制…

每日一題:LeetCode-102.二叉樹的層序遍歷

每日一題系列&#xff08;day 03&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

NX二次開發UF_CSYS_set_wcs 函數介紹

文章作者&#xff1a;里海 來源網站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_set_wcs Defined in: uf_csys.h int UF_CSYS_set_wcs(tag_t csys_id ) overview 概述 Sets the work coordinate system to the prototype coordinate system whose tag y…

為什么技術干不過產品?

近年來&#xff0c;我們經常會聽到一些關于技術和產品之間關系的討論&#xff0c;包括最近的ChatGPT之父奧特曼被董事會開除事件。在這個問題上&#xff0c;有人認為技術應該優于產品&#xff0c;因為技術是實現產品的基礎。然而&#xff0c;也有人認為產品比技術更重要&#x…

基于低代碼平臺搭建應用程序

目錄 一、背景 二、如何基于低代碼開發應用&#xff1f; 1.創建數據表 2.添加數據表屬性 3.配置功能 4.數據篩選 5.數據集顯示&功能發布 三、寫在最后 一、背景 很多時候&#xff0c;市場上的管理軟件魚龍混雜&#xff0c;找一些外包團隊在實際應用中效果并不理想&#xff…

企業微信平臺:連接你我,引領數字化未來

近年來&#xff0c;隨著移動互聯網的飛速發展&#xff0c;社交媒體平臺如微信已經成為人們生活中必不可少的一部分。對于企業而言&#xff0c;微信平臺不僅是一個重要的宣傳渠道&#xff0c;更是實現數字化轉型的關鍵工具。本文將探討企業微信平臺的發展趨勢、運營策略以及成功…

開源還是閉源(=°Д°=)!!趨勢表明,開源技術在諸多領域中日益受到重視

開源和閉源&#xff0c;兩種截然不同的開發模式&#xff0c;對于大模型的發展有著重要影響。開源讓技術共享&#xff0c;吸引了眾多人才加入&#xff0c;推動了大模的創新。而閉源則保護了商業利益和技術優勢&#xff0c;為大模型的商業應用提供了更好的保障。 一、開源和閉源的…

堆和前綴樹

1 堆 1.1 堆結構 堆是用數組實現的完全二叉樹結構完全二叉樹中如果每棵樹的最大值都在頂部就是大根堆&#xff0c;最小值在頂部就是小根堆堆結構的heapInsert就是插入操作&#xff0c;heapify是取出數組后進行堆結構調整的操作優先級隊列結構就是堆結構 public class Heap {…