Open In App

Minimum amount of lamps needed to be installed

Last Updated : 09 Sep, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given string str containing only dots and asterisk. A dot represents free spaces and *                    represents lamps. A lamp at position i                    can spread its light at locations i-1, i, and i+1. Determine the minimum number of lamps needed to illuminate the whole string.

Examples: 

Input: str = “……” 
Output:
There are initially no lamps so the whole string is in dark.We will install lamps at position 2 and 5.The lamp at position 2 will illuminate 1, 2, 3 and lamp at position 5 will illuminate 4, 5, 6 thus the whole string is illuminated.

Input: str = “*.*” 
Output:

Approach: If we don’t have an asterisk *                    then for every 3 dots we need one lamp, so the answer is ceil(D/3) where D is the number of dots. The problem can be solved by creating a copy of the given string, and for each asterisk in the first string, we place an asterisk at its adjacent indices in the second string. 
So if the given string is “…**..” then the second string will be “..****.”

After that, we count the number of dots in each block of consecutive dots and find the number of needed lamps for that block, For each block, the answer will be ceil(D/3) and the total sum of these lamps will be the answer for the complete string.

Below is the implementation of the above approach: 

C++

// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
void check(int n, string s)
{
      
    // Create the modified string with
    // v[i-1] = v[i + 1] = * where s[i] = *
    char v[n];
    for(int i = 0; i < n; i++)
    {
        if (s[i] == '*')
        {
            v[i] = '*';
              
            // Checking valid index and then replacing
            // "." with "*" on the surrounding of a *
            if (i > 0 && i < n - 1)
            {
                v[i + 1] = '*';
                v[i - 1] = '*';
            }
            if (i == 0 && n != 1)
            {
                v[i + 1] = '*';
            }
            if (i == n - 1 && n != 1)
            {
                v[i - 1] = '*';
            }
        }
        else
        {
              
            // Just copying if the character is a "."
            if (v[i] != '*')
            {
                v[i] = '.';
            }
        }
    }
  
    // Creating the string with the list v
    string str(v);
     
    string word = "";
    char dl = '*';
  
    // to count the number of split strings
    int num = 0;
  
    // adding delimiter character at the end
    // of 'str'
    str = str + dl;
  
    // length of 'str'
    int l = str.size();
  
    // traversing 'str' from left to right
    vector<string> res;
    for (int i = 0; i < l; i++) {
  
        // if str[i] is not equal to the delimiter
        // character then accumulate it to 'word'
        if (str[i] != dl)
            word += str[i];
  
        else {
  
            // if 'word' is not an empty string,
            // then add this 'word' to the array
            // 'substr_list[]'
            if ((int)word.size() != 0)
                res.push_back(word);
  
            // reset 'word'
            word = "";
        }
    }
  
    int ans = 0;
    for(auto x : res)
    {
       
        // Continuing if the string length is 0
        if (x.length() == 0)
        {
            continue;
        }
  
        // Adding number of lamps for each block of "."
        ans += ceil(x.length() * 1.0 / 3);
    }
    cout << ans << "\n";
}
 
int main() {
    string s = ".....";
    int n = s.length();
    check(n, s);
    return 0;
}
 
// This code is contributed by NishaBharti.

                    

Java

// Java implementation of the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Function to print minimum amount
// of lamps needed to be installed
static void check(int n, String s)
{
     
    // Create the modified string with
    // v[i-1] = v[i + 1] = * where s[i] = *
    char v[] = new char[n];
    for(int i = 0; i < n; i++)
    {
        if (s.charAt(i) == '*')
        {
            v[i] = '*';
             
            // Checking valid index and then replacing
            // "." with "*" on the surrounding of a *
            if (i > 0 && i < n - 1)
            {
                v[i + 1] = '*';
                v[i - 1] = '*';
            }
            if (i == 0 && n != 1)
            {
                v[i + 1] = '*';
            }
            if (i == n - 1 && n != 1)
            {
                v[i - 1] = '*';
            }
        }
        else
        {
             
            // Just copying if the character is a "."
            if (v[i] != '*')
            {
                v[i] = '.';
            }
        }
    }
 
    // Creating the string with the list v
    String xx = new String(v);
 
    // Splitting the string into blocks
    // with "*" as delimiter
    String x[] = xx.split("\\*");
 
    int ans = 0;
    for(String xi : x)
    {
         
        // Continuing if the string length is 0
        if (xi.length() == 0)
        {
            continue;
        }
 
        // Adding number of lamps for each block of "."
        ans += Math.ceil(xi.length() * 1.0 / 3);
    }
    System.out.println(ans);
}
 
// Driver Code
public static void main(String[] args)
{
    String s = "......";
    int n = s.length();
     
    check(n, s);
}
}
 
// This code is contributed by Kingash

                    

Python3

# Python3 implementation of the above approach
import math
 
# Function to print minimum amount
# of lamps needed to be installed
def check(n, s):
 
    # Create the modified string with
    # v[i-1] = v[i + 1] = * where s[i] = *
    v = [""] * n
    for i in range(n):
        if (s[i] == "*"):
            v[i] = "*"
 
            # Checking valid index and then replacing
            # "." with "*" on the surrounding of a *
            if (i > 0 and i < n - 1):
                v[i + 1] = "*"
                v[i - 1] = "*"
            if (i == 0 and n != 1):
                v[i + 1] = "*"
            if (i == n - 1 and n != 1):
                v[i - 1] = "*"
        else:
 
            # Just copying if the character is a "."
            if (v[i] != "*"):
                v[i] = "."
 
    # Creating the string with the list v
    xx = ''.join(v)
 
    # Splitting the string into blocks
    # with "*" as delimiter
    x = xx.split("*")
    s = 0
    for i in range(len(x)):
 
        # Continuing if the string length is 0
        if (x[i] == ""):
            continue
 
        # Adding number of lamps for each block of "."
        s += math.ceil(len(x[i]) / 3)
    print(s)
 
# Driver code
s = "......"
n = len(s)
check(n, s)

                    

C#

// C# implementation of the above approach
using System;
class GFG {
 
    // Function to print minimum amount
    // of lamps needed to be installed
    static void check(int n, string s)
    {
 
        // Create the modified string with
        // v[i-1] = v[i + 1] = * where s[i] = *
        char[] v = new char[n];
        for (int i = 0; i < n; i++) {
            if (s[i] == '*') {
                v[i] = '*';
 
                // Checking valid index and then replacing
                // "." with "*" on the surrounding of a *
                if (i > 0 && i < n - 1) {
                    v[i + 1] = '*';
                    v[i - 1] = '*';
                }
                if (i == 0 && n != 1) {
                    v[i + 1] = '*';
                }
                if (i == n - 1 && n != 1) {
                    v[i - 1] = '*';
                }
            }
            else {
 
                // Just copying if the character is a "."
                if (v[i] != '*') {
                    v[i] = '.';
                }
            }
        }
 
        // Creating the string with the list v
        string xx = new string(v);
 
        // Splitting the string into blocks
        // with "*" as delimiter
        string[] x = xx.Split("\\*");
 
        int ans = 0;
        foreach(string xi in x)
        {
 
            // Continuing if the string length is 0
            if (xi.Length == 0) {
                continue;
            }
 
            // Adding number of lamps for each block of "."
            ans += (int)(Math.Ceiling(xi.Length * 1.0 / 3));
        }
        Console.Write(ans);
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        string s = "......";
        int n = s.Length;
 
        check(n, s);
    }
}
 
// This code is contributed by ukasp.

                    

Javascript

<script>
    // JavaScript implementation of the above approach
    const check = (n, s) => {
 
        // Create the modified string with
        // v[i-1] = v[i + 1] = * where s[i] = *
        let v = new Array(n).fill('');
        for (let i = 0; i < n; i++)
        {
            if (s[i] == '*')
            {
                v[i] = '*';
 
                // Checking valid index and then replacing
                // "." with "*" on the surrounding of a *
                if (i > 0 && i < n - 1) {
                    v[i + 1] = '*';
                    v[i - 1] = '*';
                }
                if (i == 0 && n != 1) {
                    v[i + 1] = '*';
                }
                if (i == n - 1 && n != 1) {
                    v[i - 1] = '*';
                }
            }
            else {
 
                // Just copying if the character is a "."
                if (v[i] != '*') {
                    v[i] = '.';
                }
            }
        }
 
        // Creating the string with the list v
        let str = v.join('');
 
        let word = "";
        let dl = '*';
 
        // to count the number of split strings
        let num = 0;
 
        // adding delimiter character at the end
        // of 'str'
        str = str + dl;
 
        // length of 'str'
        let l = str.length;
 
        // traversing 'str' from left to right
        let res = [];
        for (let i = 0; i < l; i++) {
 
            // if str[i] is not equal to the delimiter
            // character then accumulate it to 'word'
            if (str[i] != dl)
                word = word + str[i];
 
            else {
 
                // if 'word' is not an empty string,
                // then add this 'word' to the array
                // 'substr_list[]'
                if (word.length != 0)
                    res.push(word);
 
                // reset 'word'
                word = "";
            }
        }
 
        let ans = 0;
        for (let x in res) {
 
            // Continuing if the string length is 0
            if (res[x].length == 0) {
                continue;
            }
 
            // Adding number of lamps for each block of "."
            ans += Math.ceil(res[x].length * 1.0 / 3);
        }
        document.write(`${ans}<br/>`);
    }
 
    let s = ".....";
    let n = s.length;
    check(n, s);
 
// This code is contributed by rakeshsahni
 
</script>

                    

Output
2

Complexity Analysis:

  • Time Complexity: O(n) as we are doing single loop traversal
  • Space Complexity: O(n) as we are creating a character array

 Note: where n is the size of the string given



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads