Day 18 (30 Days of Code)

Day 18 (30 Days of Code)

20 July 2023

Solved more questions on Dynamic Programming.

  • Loot House

A thief wants to loot houses. He knows the amount of money in each house. He cannot loot two consecutive houses. Find the maximum amount of money he can loot.

Input Format:

The first line of input contains an integer value of 'n'. It is the total number of houses.

The second line of input contains 'n' integer values separated by a single space denoting the amount of money each house has.

Output Format:

Print the the maximum money that can be looted.

Constraints:

0 <= n <= 10 ^ 4

Time Limit: 1 sec

Sample Input 1:

6
5 5 10 100 10 5

Sample Output 1:

110

Sample Input 2:

6
10 2 30 20 3 50

Sample Output 2:

90

Explanation of Sample Output 2:

Looting first, third, and the last houses([10 + 30 + 50]) will result in the maximum loot, and all the other possible combinations would result in less than 90.

My solution:

  • Brute Force (Using Recursion)
int maxMoneyLooted(int *arr, int n)
{
    //Write your code here
    if(n<=0){
        return 0;
    }

    int a = arr[0]+maxMoneyLooted(arr+2,n-2);
    int b = maxMoneyLooted(arr+1,n-1);

    return max(a,b);
}
  • Memoization
int helper(int *arr, int n, int* output){
    if(n<=0){
        return 0;
    }

    if(output[n]!=-1){
        return output[n];
    }

    int a = arr[0]+helper(arr+2,n-2,output);
    int b = helper(arr+1,n-1,output);

    output[n] = max(a,b);

    return output[n];
}
int maxMoneyLooted(int *arr, int n)
{
    //Write your code here         
    int* output = new int[n+1];

    for(int i=0;i<=n;i++){
        output[i] = -1;
    }
    return helper(arr, n, output);
}
  • Dynamic Programming
int maxMoneyLooted(int *arr, int n)
{
    //Write your code here
    int* output = new int[n];
    if(n<=0){
        return 0;
    }

    output[0] = arr[0];

    if(n>1){
        output[1] = max(arr[0],arr[1]);
    }

    int maxMoney = 0;
    for(int i=2;i<n;i++){
        output[i] = max(arr[i]+output[i-2], output[i-1]);

    }

    return output[n-1];
}
  • Longest Increasing Subsequence

Given an array with N elements, you need to find the length of the longest subsequence in the given array such that all elements of the subsequence are sorted in strictly increasing order.

Input Format:

The first line of input contains an integer N. The following line contains N space separated integers, that denote the value of elements of array.

Output Format:

The first and only line of output contains the length of longest subsequence.

Constraints:

1 <= N <= 10^3
Time Limit: 1 second

Sample Input 1:

6
5 4 11 1 16 8

Sample Output 1:

3

Sample Input 2:

3
1 2 2

Sample Output 2:

2

My approach:

In the questions of subsequence, we follow a basic approach of either choosing the element or not choosing it and we come up with a solution using all cases possible.

My solution:

  • Brute Force:
int helper(int index, int prevIndex, int arr[], int n){
    if(index==n){
        return 0;
    }

    int len = helper(index+1, prevIndex, arr, n);
    if(prevIndex==-1 || arr[index]>arr[prevIndex]){
        len = max(len,1+helper(index+1, index, arr,n));
    }
    return len;
}

int longestIncreasingSubsequence(int arr[], int n)
{
    //Write Your Code here
    return helper(0,-1,arr,n,output);

}
  • Memoization
int helper(int index, int prevIndex, int arr[], int n, int **output){
    if(index==n){
        return 0;
    }
    if(output[index][prevIndex+1]!=-1){
        return output[index][prevIndex+1];
    }
    int len = helper(index+1, prevIndex, arr, n,output);
    if(prevIndex==-1 || arr[index]>arr[prevIndex]){
        len = max(len,1+helper(index+1, index, arr,n,output));
    }
    output[index][prevIndex+1] = len;
    return len;
}

int longestIncreasingSubsequence(int arr[], int n)
{
    //Write Your Code here
    int ** output = new int*[n];
    for(int i=0;i<n;i++){
        output[i] = new int[n+1];
    }

    for(int i=0;i<n;i++){
        for(int j=0;j<=n;j++){
            output[i][j] = -1;
        }
    }
    return helper(0,-1,arr,n,output);

}
  • Dynamic Programming
int longestIncreasingSubsequence(int arr[], int n){
    int* output = new int[n];

    output[0] = 1;
    int maxLen = 1;

    for(int i=1;i<n;i++){
        output[i] = 1;
        for(int j=i-1;j>=0;j--){
            if(arr[j]<arr[i]){
                output[i] = max(output[i],1+output[j]);
            }
        }
        maxLen = max(maxLen,output[i]);
    }
    return maxLen;
}

My approach:

I was able to easily identify that we can solve it using Binary Search and that's what I did.

My solution:

class Solution {
public:
    int guessNumber(int n) {

        long long int s = 0;
        long long int e = n-1;


        while(s<=e){
            long long int mid = (s+e)/2;
            if(guess(mid)==-1){
                e = mid-1;
            }
            else if(guess(mid)==1){
                s = mid+1;
            }else{
                return mid;
            }
        }
        return n;
    }
};
  • Ransom Note

My approach:

I came up with two solutions. Firstly, to sort both the string which would take time of O(nlogn) and space would be constant. But the other way was to simply use Hashmap which made space complexity to O(n) but the time complexity also decreased to O(n).

My solution:

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        unordered_map<int,int> map;
        vector<int> v;

        for(int i=0;i<ransomNote.size();i++){
            if(map.count(ransomNote[i])>0){
                map[ransomNote[i]]++;
                continue;
            }
            map[ransomNote[i]] = 1;
            v.push_back(ransomNote[i]);
        }

        for(int i=0;i<magazine.size();i++){
            if(map.count(magazine[i])>0 && map[magazine[i]]>0){
                map[magazine[i]]--;
            }
        }

        for(int i=0;i<v.size();i++){
            if(map[v[i]]!=0){
                return false;
            }
        }
        return true;
    }
};