欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現(xiàn)LeetCode(198.打家劫舍)

 更新時間:2021年08月06日 14:27:43   作者:Grandyang  
這篇文章主要介紹了C++實現(xiàn)LeetCode(198.打家劫舍),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下

[LeetCode] 198. House Robber 打家劫舍

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.

Example 2:

Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Also thanks to @ts for adding additional test cases.

這道題的本質相當于在一列數(shù)組中取出一個或多個不相鄰數(shù),使其和最大。那么對于這類求極值的問題首先考慮動態(tài)規(guī)劃 Dynamic Programming 來解,維護一個一位數(shù)組 dp,其中 dp[i] 表示 [0, i] 區(qū)間可以搶奪的最大值,對當前i來說,有搶和不搶兩種互斥的選擇,不搶即為 dp[i-1](等價于去掉 nums[i] 只搶 [0, i-1] 區(qū)間最大值),搶即為 dp[i-2] + nums[i](等價于去掉 nums[i-1])。再舉一個簡單的例子來說明一下吧,比如說 nums為{3, 2, 1, 5},那么來看 dp 數(shù)組應該是什么樣的,首先 dp[0]=3 沒啥疑問,再看 dp[1] 是多少呢,由于3比2大,所以搶第一個房子的3,當前房子的2不搶,則dp[1]=3,那么再來看 dp[2],由于不能搶相鄰的,所以可以用再前面的一個的 dp 值加上當前的房間值,和當前房間的前面一個 dp 值比較,取較大值當做當前 dp 值,這樣就可以得到狀態(tài)轉移方程 dp[i] = max(num[i] + dp[i - 2], dp[i - 1]), 且需要初始化 dp[0] 和 dp[1],其中 dp[0] 即為 num[0],dp[1] 此時應該為 max(num[0], num[1]),代碼如下:

解法一:

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() <= 1) return nums.empty() ? 0 : nums[0];
        vector<int> dp = {nums[0], max(nums[0], nums[1])};
        for (int i = 2; i < nums.size(); ++i) {
            dp.push_back(max(nums[i] + dp[i - 2], dp[i - 1]));
        }
        return dp.back();
    }
};

還有一種解法,核心思想還是用 DP,分別維護兩個變量 robEven 和 robOdd,顧名思義,robEven 就是要搶偶數(shù)位置的房子,robOdd 就是要搶奇數(shù)位置的房子。所以在遍歷房子數(shù)組時,如果是偶數(shù)位置,那么 robEven 就要加上當前數(shù)字,然后和 robOdd 比較,取較大的來更新 robEven。這里就看出來了,robEven 組成的值并不是只由偶數(shù)位置的數(shù)字,只是當前要搶偶數(shù)位置而已。同理,當奇數(shù)位置時,robOdd 加上當前數(shù)字和 robEven 比較,取較大值來更新 robOdd,這種按奇偶分別來更新的方法,可以保證組成最大和的數(shù)字不相鄰,最后別忘了在 robEven 和 robOdd 種取較大值返回,代碼如下:

解法二:

class Solution {
public:
    int rob(vector<int>& nums) {
        int robEven = 0, robOdd = 0, n = nums.size();
        for (int i = 0; i < n; ++i) {
            if (i % 2 == 0) {
                robEven = max(robEven + nums[i], robOdd);
            } else {
                robOdd = max(robEven, robOdd + nums[i]);
            }
        }
        return max(robEven, robOdd);
    }
};

上述方法還可以進一步簡潔,我們使用兩個變量 rob 和 notRob,其中 rob 表示搶當前的房子,notRob 表示不搶當前的房子,那么在遍歷的過程中,先用兩個變量 preRob 和 preNotRob 來分別記錄更新之前的值,由于 rob 是要搶當前的房子,那么前一個房子一定不能搶,所以使用 preNotRob 加上當前的數(shù)字賦給 rob,然后 notRob 表示不能搶當前的房子,那么之前的房子就可以搶也可以不搶,所以將 preRob 和 preNotRob 中的較大值賦給 notRob,參見代碼如下:

解法三:

class Solution {
public:
    int rob(vector<int>& nums) {
        int rob = 0, notRob = 0, n = nums.size();
        for (int i = 0; i < n; ++i) {
            int preRob = rob, preNotRob = notRob;
            rob = preNotRob + nums[i];
            notRob = max(preRob, preNotRob);
        }
        return max(rob, notRob);
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/198

參考資料:

https://leetcode.com/problems/house-robber/description/

https://leetcode.com/problems/house-robber/discuss/55681/java-on-solution-space-o1

https://leetcode.com/problems/house-robber/discuss/55693/c-1ms-o1space-very-simple-solution

https://leetcode.com/problems/house-robber/discuss/55695/java-dp-solution-on-runtime-and-o1-space-with-inline-comment

到此這篇關于C++實現(xiàn)LeetCode(198.打家劫舍)的文章就介紹到這了,更多相關C++實現(xiàn)打家劫舍內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 優(yōu)秀程序員必須知道的20個位運算技巧

    優(yōu)秀程序員必須知道的20個位運算技巧

    掌握簡單的位運算技巧還是必要的,所以今天寫這篇文章把我積累的一些位運算技巧分享給大家,這些技巧不會是如求“1的數(shù)目”的技巧,是最基本的一行位運算技巧
    2013-09-09
  • C語言實現(xiàn)簡單計算器功能(1)

    C語言實現(xiàn)簡單計算器功能(1)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)簡單計算器功能的第一部分,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • 華為面試題數(shù)字大小寫轉換

    華為面試題數(shù)字大小寫轉換

    一個四位數(shù),如1024,1004,打印出他們的中文形式,如果一千零二十四,一千零四,大家參考使用吧
    2013-12-12
  • C語言數(shù)據(jù)結構之單鏈表的查找和建立

    C語言數(shù)據(jù)結構之單鏈表的查找和建立

    鏈表是一種物理存儲結構上非連續(xù)、非順序的存儲結構,數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序實現(xiàn)的。本文將和大家一起聊聊C語言中單鏈表的查找和建立,感興趣的可以學習一下
    2022-09-09
  • C++語言實現(xiàn)hash表詳解及實例代碼

    C++語言實現(xiàn)hash表詳解及實例代碼

    這篇文章主要介紹了C++語言實現(xiàn)hash表詳解及實例代碼的相關資料,需要的朋友可以參考下
    2017-01-01
  • C語言驅動開發(fā)之通過ReadFile與內核層通信

    C語言驅動開發(fā)之通過ReadFile與內核層通信

    驅動與應用程序的通信是非常有必要的,內核中執(zhí)行代碼后需要將其動態(tài)顯示給應用層。為了實現(xiàn)內核與應用層數(shù)據(jù)交互則必須有通信的方法,微軟為我們提供了三種通信方式,本文先來介紹通過ReadFile系列函數(shù)實現(xiàn)的通信模式
    2022-09-09
  • C++函數(shù)模板學習示例教程指南

    C++函數(shù)模板學習示例教程指南

    這篇文章主要為大家介紹了C++函數(shù)模板學習示例教程指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • C/C++中線程基本概念與創(chuàng)建詳解

    C/C++中線程基本概念與創(chuàng)建詳解

    線程是在進程中產生的一個執(zhí)行單元,是CPU調度和分配的最小單元,其在同一個進程中與其他線程并行運行,他們可以共享進程內的資源。本文就和大家一起聊聊線程基本概念以及如何創(chuàng)建多線程,需要的可以參考一下
    2022-09-09
  • C語言數(shù)據(jù)結構之堆、堆排序的分析及實現(xiàn)

    C語言數(shù)據(jù)結構之堆、堆排序的分析及實現(xiàn)

    堆是一個近似完全二叉樹的結構,并同時滿足堆積的性質,下面這篇文章主要給大家介紹了關于C語言數(shù)據(jù)結構之堆、堆排序的分析及實現(xiàn)的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-04-04
  • C++11中列表初始化機制的概念與實例詳解

    C++11中列表初始化機制的概念與實例詳解

    在我們實際編程中,我們經(jīng)常會碰到變量初始化的問題,對于不同的變量初始化的手段多種多樣,下面這篇文章主要給大家介紹了關于C++11中列表初始化機制的相關資料,需要的朋友可以參考下
    2021-11-11

最新評論