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 2Input: 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:
#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;
}
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();
}
}
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)
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();
}
}
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)