3228. Maximum Number of Operations to Move Ones to the End
Problem Description
You are given a binary string s
.
You can perform the following operation on the string any number of times:
- Choose any index
i
from the string wherei + 1 < s.length
such thats[i] == '1'
ands[i + 1] == '0'
. - Move the character
s[i]
to the right until it reaches the end of the string or another1
. For example, fors = "010010"
, if we choosei = 1
, the resulting string will bes = "0<strong><u>001</u></strong>10"
.
Return the maximum number of operations that you can perform.
Intuition
The problem revolves around shifting 1
s past 0
s efficiently in the binary string to maximize the number of such shifts. To find a solution, we can utilize a greedy approach:
-
Track
1
s with Counting: We maintain a countercnt
to record the number of1
s encountered so far. This is useful because any contiguous set of1
s can potentially be shifted past a0
that follows these1
s. -
Iterate Through the String: As we iterate through the string, each time we encounter a
1
, we increment ourcnt
. Whenever we hit a0
and the previous character is a1
, it indicates a possible shift operation for all1
s counted. -
Count the Operations: For each possible move operation, add the current
cnt
to the total number of operations since these many1
s can effectively be shifted past the0
.
In essence, the logic is about counting how many 1
s can be shifted past every 0
encountered right after a block of 1
s, leveraging these counts for the maximum number of operations possible.
Learn more about Greedy patterns.
Solution Approach
To solve this problem, we employ a greedy approach with two main components: counting and iterating. Here's a structured breakdown of the implementation:
-
Initialize Variables:
- We initiate two variables:
ans
to store the final count of maximum operations andcnt
to count the current number of1
s encountered in the string.
- We initiate two variables:
-
Iterate Through the String:
- We loop through each character (
c
) in the strings
using an indexi
.
- We loop through each character (
-
Count the
1
s:- If the current character
c
is1
, we incrementcnt
by one. This counting tracks how many1
s can potentially be moved.
- If the current character
-
Check and Calculate Operations at
0
s:- If the current character is
0
, and the previous character (s[i-1]
) is1
, it indicates the end of a segment that can be shifted. - Increase
ans
by the numbercnt
, since all counted1
s can slide past this0
.
- If the current character is
-
Return the Result:
- After completing the iteration over
s
,ans
will hold the total number of shift operations that were possible, which we return as the result.
- After completing the iteration over
In code, this approach is implemented as follows:
class Solution:
def maxOperations(self, s: str) -> int:
ans = cnt = 0
for i, c in enumerate(s):
if c == "1":
cnt += 1
elif i and s[i - 1] == "1":
ans += cnt
return ans
In summary, this solution effectively calculates the maximum number of operations by leveraging the properties of binary strings and using a count to track movable 1
s as it progresses through each character.
Ready to land your dream job?
Unlock your dream job with a 2-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's consider the binary string s = "1101000"
to illustrate the solution approach.
-
Initialization:
- Set
ans = 0
to store the total operations. - Set
cnt = 0
to count the number of1
s seen so far.
- Set
-
Iterate Through the String:
- Index 0:
c = '1'
- Increment
cnt
to 1.
- Increment
- Index 1:
c = '1'
- Increment
cnt
to 2.
- Increment
- Index 2:
c = '0'
- The previous character was a
1
, which means we can shift1
s past this0
. - Add
cnt
(which is 2) toans
. Now,ans = 2
.
- The previous character was a
- Index 3:
c = '1'
- Increment
cnt
to 3.
- Increment
- Index 4:
c = '0'
- The previous character was a
1
, again allowing a shift. - Add
cnt
(which is 3) toans
. Now,ans = 5
.
- The previous character was a
- Index 5:
c = '0'
- No shift possible since the previous character was not a
1
.
- No shift possible since the previous character was not a
- Index 6:
c = '0'
- Similarly, no shift is possible here.
- Index 0:
-
Return the Result:
- The total number of shift operations is
ans = 5
.
- The total number of shift operations is
Thus, the maximum number of operations that can be performed is 5, where we shift 1
s past 0
s at indices 2 and 4.
Solution Implementation
1class Solution:
2 def maxOperations(self, s: str) -> int:
3 # Initialize ans to count the number of operations, cnt to count consecutive '1's
4 ans = 0
5 cnt = 0
6
7 # Loop through each character in the string, along with its index
8 for i, c in enumerate(s):
9 if c == "1":
10 # If the current character is '1', increment the counter for consecutive '1's
11 cnt += 1
12 elif i > 0 and s[i - 1] == "1":
13 # If the current character is not '1' but the previous one is, it means
14 # we have encountered a complete sequence of consecutive '1's
15 # Increase the answer by the number of consecutive '1's
16 ans += cnt
17 # Reset the cnt as the sequence of consecutive '1's is broken
18 cnt = 0
19
20 # There could be a sequence of '1's at the end, we should check for it
21 if cnt > 0:
22 ans += cnt
23
24 return ans
25
1class Solution {
2 public int maxOperations(String s) {
3 int ans = 0; // This will hold the count of operations
4 int cnt = 0; // Temporary count for consecutive '1's
5 int n = s.length(); // Length of the string
6
7 // Iterate through the string
8 for (int i = 0; i < n; ++i) {
9 // If the current character is '1', increment 'cnt'
10 if (s.charAt(i) == '1') {
11 ++cnt;
12 }
13 // If the current character is '0' and the previous character was '1'
14 else if (i > 0 && s.charAt(i - 1) == '1') {
15 ans += cnt; // Increment 'ans' by the count of '1's seen
16 cnt = 0; // Reset the count
17 }
18 }
19
20 // Return the total number of operations
21 return ans;
22 }
23}
24
1class Solution {
2public:
3 // Function to calculate the maximum operations in the string
4 int maxOperations(std::string s) {
5 int answer = 0; // Initialize the answer to store the number of operations
6 int countOnes = 0; // Counter for consecutive '1's in the string
7 int length = s.size(); // Get the length of the string
8
9 // Loop through each character in the string
10 for (int i = 0; i < length; ++i) {
11 if (s[i] == '1') {
12 // If character is '1', increment the '1's counter
13 ++countOnes;
14 } else if (i > 0 && s[i - 1] == '1') {
15 // If current character is not '1' and previous character was '1',
16 // add the count of '1's to the answer and reset counter
17 answer += countOnes;
18 countOnes = 0;
19 }
20 }
21
22 return answer; // Return the total maximum operations
23 }
24};
25
1function maxOperations(s: string): number {
2 // Initialize the answer and count variables
3 let ans = 0; // To store the result of maximum operations
4 let cnt = 0; // To count consecutive '1's
5
6 const n = s.length; // Store the length of the input string
7
8 // Iterate over each character of the string
9 for (let i = 0; i < n; ++i) {
10 if (s[i] === '1') {
11 // If the current character is '1', increment the count of consecutive '1's
12 ++cnt;
13 } else if (i > 0 && s[i - 1] === '1') {
14 // If the current character is '0' and the previous character was '1'
15 // Add the count of '1's to the answer (this simulates an operation)
16 ans += cnt;
17 }
18 }
19
20 return ans; // Return the total number of operations
21}
22
Time and Space Complexity
The time complexity of the code is O(n)
, where n
is the length of the string s
. This is because the code iterates through the string s
once, performing constant-time operations for each character.
The space complexity is O(1)
because the code uses a constant amount of extra space regardless of the input size. The variables ans
and cnt
do not depend on the length of the input string.
Learn more about how to find time and space complexity quickly.
You are given an array of intervals where intervals[i] = [start_i, end_i]
represent the start and end of the ith
interval. You need to merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input.
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https algomonster s3 us east 2 amazonaws com recursion jpg You first
Want a Structured Path to Master System Design Too? Donโt Miss This!