Open In App

Minimum Moves for adjacent stars

Last Updated : 31 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string s consisting of ‘.’ and ‘*’, In one move you can shift ‘*’, one index left or one index right if there is a ‘.’ present there, the task is to make an arrangement such that all the * are adjacent to each other i.e. there is no ‘.’ between any two ‘*’ Print the minimum number of moves required to do so.

Examples:

Input: s = **.*..
Output: 1
Explanation: Shift the * at index 3 to index 2

Input: s = *.*…*.**
Output: 9

Approach: To solve the problem follow the below idea:

The idea is to first identify the position of the middle ‘*’ character, then calculate the absolute difference between each ‘*’ character and its expected position in the rearranged sequence, adding up these differences to obtain the total minimum moves.

Step-by-step approach:

  • Count the number of ‘*’ characters in the count
  • Find the middle ‘*’ position in pos:
  • Calculate the minimum moves:
    • Initialize curr_count on the position of the middle ‘*’ character by corr_count = pos – count / 2.
    • Iterate through the string for i = 0 to n:
      • For each ‘*’ character encountered, calculate the absolute difference between the current position and the position of the ‘*’ character.
      • Add this absolute difference to the answer ans (i.e, ans += abs(corr_count – i))
      • Increment the current position.
  • Return the ans

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
 
using namespace std;
 
// Function to solve the problem and calculate the
// minimum number of moves
long long solve(int n, string& s)
{
    // Count of '*' characters in the string
    int count = 0;
    for (auto x : s)
        count += (x == '*' ? 1 : 0);
 
    // Position of the middle '*' character
    int pos = -1;
 
    // Current count of '*' characters encountered
    int corr_count = -1;
    for (int i = 0; i < n; i++) {
        if (s[i] == '*') {
            corr_count++;
 
            // Mark the position of the middle '*' character
            if (corr_count == count / 2)
                pos = i;
        }
    }
 
    long long ans = 0;
 
    // Initialize the current position based on the middle
    // '*' character
    corr_count = pos - count / 2;
    for (int i = 0; i < n; i++)
        if (s[i] == '*') {
 
            // Calculate the absolute difference and add to
            // the answer
            ans += abs(corr_count - i);
            corr_count++;
        }
 
    // Return the minimum number of moves
    return ans;
}
 
// Drivers code
int main()
{
    long long n = 10;
    string s = "*.*...*.**";
    long long result = solve(n, s);
    cout << result << endl;
 
    return 0;
}


Java




import java.util.Scanner;
 
public class MinMoves {
    // Function to solve the problem and calculate the
    // minimum number of moves
    static long solve(int n, String s)
    {
        // Count of '*' characters in the string
        int count = 0;
        for (char x : s.toCharArray())
            count += (x == '*' ? 1 : 0);
 
        // Position of the middle '*' character
        int pos = -1;
 
        // Current count of '*' characters encountered
        int corr_count = -1;
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '*') {
                corr_count++;
 
                // Mark the position of the middle '*'
                // character
                if (corr_count == count / 2)
                    pos = i;
            }
        }
 
        long ans = 0;
 
        // Initialize the current position based on the
        // middle
        // '*' character
        corr_count = pos - count / 2;
        for (int i = 0; i < n; i++)
            if (s.charAt(i) == '*') {
 
                // Calculate the absolute difference and add
                // to the answer
                ans += Math.abs(corr_count - i);
                corr_count++;
            }
 
        // Return the minimum number of moves
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        int n = 10;
        String s = "*.*...*.**";
        long result = solve(n, s);
        System.out.println(result);
        scanner.close();
    }
}


Python3




def solve(n, s):
    # Count of '*' characters in the string
    count = s.count('*')
 
    # Position of the middle '*' character
    pos = -1
 
    # Current count of '*' characters encountered
    corr_count = -1
    for i in range(n):
        if s[i] == '*':
            corr_count += 1
 
            # Mark the position of the middle '*' character
            if corr_count == count // 2:
                pos = i
 
    ans = 0
 
    # Initialize the current position based on the middle
    # '*' character
    corr_count = pos - count // 2
    for i in range(n):
        if s[i] == '*':
 
            # Calculate the absolute difference and add to
            # the answer
            ans += abs(corr_count - i)
            corr_count += 1
 
    # Return the minimum number of moves
    return ans
 
# Driver code
n = 10
s = "*.*...*.**"
result = solve(n, s)
print(result)


C#




using System;
 
class Program
{
    // Function to solve the problem and calculate the
    // minimum number of moves
    static long Solve(int n, string s)
    {
        // Count of '*' characters in the string
        int count = 0;
        foreach (char x in s)
        {
            count += (x == '*' ? 1 : 0);
        }
 
        // Position of the middle '*' character
        int pos = -1;
 
        // Current count of '*' characters encountered
        int corrCount = -1;
        for (int i = 0; i < n; i++)
        {
            if (s[i] == '*')
            {
                corrCount++;
 
                // Mark the position of the middle '*' character
                if (corrCount == count / 2)
                {
                    pos = i;
                }
            }
        }
 
        long ans = 0;
 
        // Initialize the current position based on the middle
        // '*' character
        corrCount = pos - count / 2;
        for (int i = 0; i < n; i++)
        {
            if (s[i] == '*')
            {
                // Calculate the absolute difference and add to
                // the answer
                ans += Math.Abs(corrCount - i);
                corrCount++;
            }
        }
 
        // Return the minimum number of moves
        return ans;
    }
 
    // Driver code
    static void Main(string[] args)
    {
        int n = 10;
        string s = "*.*...*.**";
        long result = Solve(n, s);
        Console.WriteLine(result);
 
        // Keep the console window open
        Console.ReadLine();
    }
}


Javascript




function solve(n, s) {
    // Count of '*' characters in the string
    const count = (s.match(/\*/g) || []).length;
 
    // Position of the middle '*' character
    let pos = -1;
 
    // Current count of '*' characters encountered
    let corrCount = -1;
    for (let i = 0; i < n; i++) {
        if (s[i] === '*') {
            corrCount += 1;
 
            // Mark the position of the middle '*' character
            if (corrCount === Math.floor(count / 2)) {
                pos = i;
            }
        }
    }
 
    let ans = 0;
 
    // Initialize the current position based on the middle
    // '*' character
    corrCount = pos - Math.floor(count / 2);
    for (let i = 0; i < n; i++) {
        if (s[i] === '*') {
 
            // Calculate the absolute difference and add to
            // the answer
            ans += Math.abs(corrCount - i);
            corrCount += 1;
        }
    }
 
    // Return the minimum number of moves
    return ans;
}
 
// Driver code
const n = 10;
const s = "*.*...*.**";
const result = solve(n, s);
console.log(result);


Output

9




Time Complexity: O(n)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads