打家劫舍
有N栋房子排成一排,每栋房子都有一些现金。小偷要偷走这些房子中的现金,但他不能偷窃相邻的两栋房子,因为被盗房子的主人会告诉他的左右两侧的邻居。任务是找出小偷最多可以盗走多少现金。
例子:
输入:hval[] = {6, 7, 1, 3, 8, 2, 4}
输出:19
解释: 小偷将从房子里偷走 6、1、8 和 4。
输入:hval[] = {5, 3, 4, 11, 2}
输出:16
解释:小偷会偷走 5 和 11
动态规划(自上而下的方法):
请按照以下步骤实施该想法:
- 创建一个大小为 n+1、值为 -1 的 DP 数组,变量 pick 和 not pick。
- 创建一个递归函数 maxLoot
- 如果 n < 0,则返回 0。
- 如果n = 0,则返回 hval[0]。
- 如果 DP[n] != -1,则返回 DP[n]。
- 如果第 n 个房子被偷, 那么 第 n-1 个房子必不能偷,只能从第 n-2 个 房子起偷,所以 pick = hval[n] + maxLoot(hval, n-2, DP)
- 如果第 n 个房子没有被偷,那么 notPick = maxLoot(hval, n-1, DP)。
- 设置 Dp[n] = max(pick, notPick) 并返回 DP[n]。
下面是上述方法的实现:
C++
// CPP program to find the maximum stolen value
#include <bits/stdc++.h>
using namespace std;
// calculate the maximum stolen value
int maxLoot(int *hval, int n, vector<int> &dp){
// base case
if(n < 0){
return 0 ;
}
if(n == 0){
return hval[0] ;
}
// If the subproblem is already solved
// then return its value
if(dp[n] != -1 ){
return dp[n] ;
}
//if current element is pick then previous cannot be picked
int pick = hval[n] + maxLoot(hval, n-2, dp) ;
//if current element is not picked then previous element is picked
int notPick = maxLoot(hval, n-1, dp) ;
// return max of picked and not picked
return dp[n] = max(pick, notPick) ;
}
// Driver to test above code
int main()
{
int hval[] = {6, 7, 1, 3, 8, 2, 4};
int n = sizeof(hval)/sizeof(hval[0]);
// Initialize a dp vector
vector<int> dp(n+1, -1) ;
cout << "Maximum loot possible : "
<< maxLoot(hval, n-1, dp);
return 0;
}
Java
/*package whatever //do not write package name here */
// Java program to find the maximum stolen value
import java.io.*;
import java.util.Arrays;
class GFG {
// Function to calculate the maximum stolen value
static int maxLoot(int hval[], int n, int dp[])
{
// base case
if (n < 0) {
return 0;
}
if (n == 0) {
return hval[0];
}
// If the subproblem is already solved
// then return its value
if (dp[n] != -1) {
return dp[n];
}
// if current element is pick then previous cannot
// be picked
int pick = hval[n] + maxLoot(hval, n - 2, dp);
// if current element is not picked then previous
// element is picked
int notPick = maxLoot(hval, n - 1, dp);
// return max of picked and not picked
return dp[n] = Math.max(pick, notPick);
}
// Driver program
public static void main(String[] args)
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = hval.length;
int dp[] = new int[n + 1];
Arrays.fill(dp, -1);
System.out.println("Maximum loot possible : "
+ maxLoot(hval, n - 1, dp));
}
}
Python
# Python3 program to find the maximum stolen value
# calculate the maximum stolen value
def maxLoot(hval, n, dp):
# base case
if(n < 0):
return 0
if(n == 0):
return hval[0]
# If the subproblem is already solved
# then return its value
if(dp[n] != -1):
return dp[n]
# if current element is pick then previous cannot be picked
pick = hval[n] + maxLoot(hval, n-2, dp)
# if current element is not picked then previous element is picked
notPick = maxLoot(hval, n-1, dp)
# return max of picked and not picked
dp[n] = max(pick, notPick)
return dp[n]
# Driver to test above code
hval = [6, 7, 1, 3, 8, 2, 4]
n = len(hval)
# Initialize a dp vector
dp = [-1 for i in range(n+1)]
print("Maximum loot possible : "+str(maxLoot(hval, n-1, dp)))
C#
// C# program to find the maximum stolen value
using System;
public class GFG {
// Function to calculate the maximum stolen value
static int maxLoot(int[] hval, int n, int[] dp)
{
// base case
if (n < 0) {
return 0;
}
if (n == 0) {
return hval[0];
}
// If the subproblem is already solved
// then return its value
if (dp[n] != -1) {
return dp[n];
}
// if current element is pick then previous cannot
// be picked
int pick = hval[n] + maxLoot(hval, n - 2, dp);
// if current element is not picked then previous
// element is picked
int notPick = maxLoot(hval, n - 1, dp);
// return max of picked and not picked
return dp[n] = Math.Max(pick, notPick);
}
static public void Main()
{
// Code
int[] hval = { 6, 7, 1, 3, 8, 2, 4 };
int n = hval.Length;
int[] dp = new int[n + 1];
Array.Fill(dp, -1);
Console.WriteLine("Maximum loot possible : "
+ maxLoot(hval, n - 1, dp));
}
}
Javascript
<script>
// JavaScript program to find the maximum stolen value
// calculate the maximum stolen value
function maxLoot(hval,n,dp){
// base case
if(n < 0){
return 0 ;
}
if(n == 0){
return hval[0] ;
}
// If the subproblem is already solved
// then return its value
if(dp[n] != -1 ){
return dp[n] ;
}
//if current element is pick then previous cannot be picked
let pick = hval[n] + maxLoot(hval, n-2, dp) ;
//if current element is not picked then previous element is picked
let notPick = maxLoot(hval, n-1, dp) ;
// return max of picked and not picked
return dp[n] = Math.max(pick, notPick) ;
}
// Driver to test above code
let hval = [6, 7, 1, 3, 8, 2, 4];
let n = hval.length;
// Initialize a dp vector
let dp = new Array(n+1).fill(-1) ;
document.write("Maximum loot possible : ",maxLoot(hval, n-1, dp),"</br>");
</script>
输出
Maximum loot possible : 19
时间复杂度:O(n)。只需要对原始数组进行一次遍历。所以时间复杂度是O(n)
空间复杂度:O(n)。
动态规划(自下而上方法):
请按照以下步骤实施该想法:
- 创建一个额外空间的DP数组来存储子问题。
- 处理以下基本情况,
- 如果数组长度为0,则打印0。
- 如果数组长度为1,则打印第一个元素。
- 如果数组长度为2,则打印两个元素中的较大值。
- 将 dp[0] 更新为 array[0],将 dp[1] 更新为 array[0] 和 array[1] 中的最大值
- 从第二个元素(第二个索引)遍历数组到数组末尾。
- 对于每个索引,将 dp[i] 更新为 dp[i-2] + array[i] 和 dp[i-1] 中的最大值,此步骤定义了两种情况:如果选择了一个元素,则前一个元素不能被选择,如果未选择,则可以选择前一个元素。
- 打印值 dp[n-1]
下面是上述方法的实现:
C++
// CPP program to find the maximum stolen value
#include <iostream>
using namespace std;
// calculate the maximum stolen value
int maxLoot(int* hval, int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return max(hval[0], hval[1]);
// dp[i] represent the maximum value stolen
// so far after reaching house i.
int dp[n];
// Initialize the dp[0] and dp[1]
dp[0] = hval[0];
dp[1] = max(hval[0], hval[1]);
// Fill remaining positions
for (int i = 2; i < n; i++)
dp[i] = max(hval[i] + dp[i - 2], dp[i - 1]);
return dp[n - 1];
}
// Driver to test above code
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof(hval) / sizeof(hval[0]);
cout << "Maximum loot possible : " << maxLoot(hval, n);
return 0;
}
C
// C program to find the maximum stolen value
#include <stdio.h>
// Find maximum between two numbers.
int max(int num1, int num2)
{
return (num1 > num2) ? num1 : num2;
}
// calculate the maximum stolen value
int maxLoot(int* hval, int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return max(hval[0], hval[1]);
// dp[i] represent the maximum value stolen
// so far after reaching house i.
int dp[n];
// Initialize the dp[0] and dp[1]
dp[0] = hval[0];
dp[1] = max(hval[0], hval[1]);
// Fill remaining positions
for (int i = 2; i < n; i++)
dp[i] = max(hval[i] + dp[i - 2], dp[i - 1]);
return dp[n - 1];
}
// Driver to test above code
int main()
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof(hval) / sizeof(hval[0]);
printf("Maximum loot possible : %d", maxLoot(hval, n));
return 0;
}
Java
// Java program to find the maximum stolen value
import java.io.*;
class GFG {
// Function to calculate the maximum stolen value
static int maxLoot(int hval[], int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return Math.max(hval[0], hval[1]);
// dp[i] represent the maximum value stolen
// so far after reaching house i.
int[] dp = new int[n];
// Initialize the dp[0] and dp[1]
dp[0] = hval[0];
dp[1] = Math.max(hval[0], hval[1]);
// Fill remaining positions
for (int i = 2; i < n; i++)
dp[i]
= Math.max(hval[i] + dp[i - 2], dp[i - 1]);
return dp[n - 1];
}
// Driver program
public static void main(String[] args)
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = hval.length;
System.out.println("Maximum loot possible : " + maxLoot(hval, n));
}
}
Python
# Python3 program to find the maximum stolen value
# calculate the maximum stolen value
def maximize_loot(hval, n):
if n == 0:
return 0
if n == 1:
return hval[0]
if n == 2:
return max(hval[0], hval[1])
# dp[i] represent the maximum value stolen so
# for after reaching house i.
dp = [0]*n
# Initialize the dp[0] and dp[1]
dp[0] = hval[0]
dp[1] = max(hval[0], hval[1])
# Fill remaining positions
for i in range(2, n):
dp[i] = max(hval[i]+dp[i-2], dp[i-1])
return dp[-1]
# Driver to test above code
def main():
# Value of houses
hval = [6, 7, 1, 3, 8, 2, 4]
# number of houses
n = len(hval)
print("Maximum loot possible : {}".
format(maximize_loot(hval, n)))
if __name__ == '__main__':
main()
C#
// C# program to find the
// maximum stolen value
using System;
class GFG
{
// Function to calculate the
// maximum stolen value
static int maxLoot(int []hval, int n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return Math.Max(hval[0], hval[1]);
// dp[i] represent the maximum value stolen
// so far after reaching house i.
int[] dp = new int[n];
// Initialize the dp[0] and dp[1]
dp[0] = hval[0];
dp[1] = Math.Max(hval[0], hval[1]);
// Fill remaining positions
for (int i = 2; i<n; i++)
dp[i] = Math.Max(hval[i]+dp[i-2], dp[i-1]);
return dp[n-1];
}
// Driver program
public static void Main ()
{
int []hval = {6, 7, 1, 3, 8, 2, 4};
int n = hval.Length;
Console.WriteLine("Maximum loot possible : " +
maxLoot(hval, n));
}
}
PHP
<?php
// PHP program to find
// the maximum stolen value
// calculate the maximum
// stolen value
function maxLoot($hval, $n)
{
if ($n == 0)
return 0;
if ($n == 1)
return $hval[0];
if ($n == 2)
return max($hval[0],
$hval[1]);
// dp[i] represent the maximum
// value stolen so far after
// reaching house i.
$dp = array();
// Initialize the
// dp[0] and dp[1]
$dp[0] = $hval[0];
$dp[1] = max($hval[0],
$hval[1]);
// Fill remaining positions
for ($i = 2; $i < $n; $i++)
$dp[$i] = max($hval[$i] +
$dp[$i - 2],
$dp[$i - 1]);
return $dp[$n - 1];
}
// Driver Code
$hval = array(6, 7, 1,
3, 8, 2, 4);
$n = sizeof($hval);
echo "Maximum loot possible : ",
maxLoot($hval, $n);
?>
Javascript
<script>
// Javascript program to find
// the maximum stolen value
// Function to calculate the
// maximum stolen value
function maxLoot(hval, n)
{
if (n == 0)
return 0;
if (n == 1)
return hval[0];
if (n == 2)
return Math.max(hval[0], hval[1]);
// dp[i] represent the maximum value stolen
// so far after reaching house i.
let dp = new Array(n);
// Initialize the dp[0] and dp[1]
dp[0] = hval[0];
dp[1] = Math.max(hval[0], hval[1]);
// Fill remaining positions
for (let i = 2; i<n; i++)
dp[i] = Math.max(hval[i]+dp[i-2], dp[i-1]);
return dp[n-1];
}
let hval = [6, 7, 1, 3, 8, 2, 4];
let n = hval.length;
document.write(
"Maximum loot possible : " + maxLoot(hval, n)
);
</script>
输出
Maximum loot possible : 19
时间复杂度:O(N)。只需要对原始数组进行一次遍历。所以时间复杂度是O(n)
辅助空间:O(N)。需要一个大小为 n 的数组,因此空间复杂度为 O(n)。
使用常数 空间:
仔细观察DP数组,可以看出在计算一个索引的值时,前两个索引的值很重要。可以用两个变量替换 DP 数组。
请按照以下步骤实施该想法:
- 处理一些基本情况,如果数组长度为0,则打印0,如果数组长度为1,则打印第一个元素,如果数组长度为2,则打印两元素中的较大值。
- 创建两个变量value1和value2,value1作为array[0],value2作为array[0]和array[1]的最大值,以及一个变量max_val来存储答案
- 从第二个元素(第二个索引)遍历数组到数组末尾。
- 对于每个索引,将 max_val 更新为 value1 + array[i] 和 value2 中的最大值,这一步定义了两种情况,如果一个元素被选择,则前一个元素不能被选择,如果一个元素没有被选择,则前一个元素可以选择。
- 对于每个索引,更新 value1 = value2 且 value2 = max_val
- 打印max_val的值
下面是上述方法的实现:
C++
// C++ program to find the maximum stolen value
#include <iostream>
using namespace std;
// calculate the maximum stolen value
int maxLoot(int* hval, int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = max(hval[0], hval[1]);
if (n == 2)
return value2;
// contains maximum stolen value at the end
int max_val;
// Fill remaining positions
for (int i = 2; i < n; i++) {
max_val = max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
// Driver to test above code
int main()
{
// Value of houses
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof(hval) / sizeof(hval[0]);
cout << "Maximum loot possible : " << maxLoot(hval, n);
return 0;
}
C
// C program to find the maximum stolen value
#include <stdio.h>
//Find maximum between two numbers.
int max(int num1, int num2)
{
return (num1 > num2) ? num1 : num2;
}
// calculate the maximum stolen value
int maxLoot(int* hval, int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = max(hval[0], hval[1]);
if (n == 2)
return value2;
// contains maximum stolen value at the end
int max_val;
// Fill remaining positions
for (int i = 2; i < n; i++) {
max_val = max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
// Driver to test above code
int main()
{
// Value of houses
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = sizeof(hval) / sizeof(hval[0]);
printf("Maximum loot possible : %d", maxLoot(hval, n));
return 0;
}
Java
// Java program to find the maximum stolen value
import java.io.*;
class GFG {
// Function to calculate the maximum stolen value
static int maxLoot(int hval[], int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = Math.max(hval[0], hval[1]);
if (n == 2)
return value2;
// contains maximum stolen value at the end
int max_val = 0;
// Fill remaining positions
for (int i = 2; i < n; i++) {
max_val = Math.max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
// driver program
public static void main(String[] args)
{
int hval[] = { 6, 7, 1, 3, 8, 2, 4 };
int n = hval.length;
System.out.println("Maximum loot possible : "
+ maxLoot(hval, n));
}
}
Python
# Python3 program to find the maximum stolen value
# calculate the maximum stolen value
def maximize_loot(hval, n):
if n == 0:
return 0
value1 = hval[0]
if n == 1:
return value1
value2 = max(hval[0], hval[1])
if n == 2:
return value2
# contains maximum stolen value at the end
max_val = None
# Fill remaining positions
for i in range(2, n):
max_val = max(hval[i]+value1, value2)
value1 = value2
value2 = max_val
return max_val
# Driver to test above code
def main():
# Value of houses
hval = [6, 7, 1, 3, 8, 2, 4]
# number of houses
n = len(hval)
print("Maximum loot possible : {}".format(maximize_loot(hval, n)))
if __name__ == '__main__':
main()
C#
// C# program to find the
// maximum stolen value
using System;
public class GFG
{
// Function to calculate the
// maximum stolen value
static int maxLoot(int []hval, int n)
{
if (n == 0)
return 0;
int value1 = hval[0];
if (n == 1)
return value1;
int value2 = Math.Max(hval[0], hval[1]);
if (n == 2)
return value2;
// contains maximum stolen value at the end
int max_val = 0;
// Fill remaining positions
for (int i = 2; i < n; i++)
{
max_val = Math.Max(hval[i] + value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
// Driver program
public static void Main ()
{
int []hval = {6, 7, 1, 3, 8, 2, 4};
int n = hval.Length;
Console.WriteLine("Maximum loot possible : " +
maxLoot(hval, n));
}
}
PHP
<?php
// PHP program to find
// the maximum stolen value
// calculate the
// maximum stolen value
function maxLoot($hval, $n)
{
if ($n == 0)
return 0;
$value1 = $hval[0];
if ($n == 1)
return $value1;
$value2 = max($hval[0],
$hval[1]);
if ($n == 2)
return $value2;
// contains maximum
// stolen value at the end
$max_val;
// Fill remaining positions
for ($i = 2; $i < $n; $i++)
{
$max_val = max($hval[$i] +
$value1, $value2);
$value1 = $value2;
$value2 = $max_val;
}
return $max_val;
}
// Driver code
$hval = array(6, 7, 1, 3, 8, 2, 4);
$n = sizeof($hval);
echo "Maximum loot possible : ",
maxLoot($hval, $n);
?>
Javascript
<script>
// Javascript program to find the
// maximum stolen value
// Function to calculate the
// maximum stolen value
function maxLoot(hval, n)
{
if (n == 0)
return 0;
let value1 = hval[0];
if (n == 1)
return value1;
let value2 = Math.max(hval[0], hval[1]);
if (n == 2)
return value2;
// contains maximum stolen value at the end
let max_val = 0;
// Fill remaining positions
for (let i = 2; i < n; i++)
{
max_val = Math.max(hval[i] +
value1, value2);
value1 = value2;
value2 = max_val;
}
return max_val;
}
let hval = [6, 7, 1, 3, 8, 2, 4];
let n = hval.length;
document.write("Maximum loot possible : "
+ maxLoot(hval, n));
</script>
输出
Maximum loot possible : 19
时间复杂度:O(N),只需遍历一次原数组。所以时间复杂度是O(N)。
辅助空间:O(1),不需要额外的空间,所以空间复杂度是恒定的。