AMAZON Coding Question – Solved

6 Live
Database security and authentication have become vital due to the increasing number of cyberattacks every day. Amazon has created a team for the analysis of various types of cyberattacks. In one such analysis, the team finds a virus that attacks the user passwords. The virus designed has an attacking rule defined by attackOrder, which is a permutation of length n. In the ith second of the attack, the virus attacks at the attackOrder[i]th character of the password, replacing it with the malicious character '*', i.e., password[attackOrder[i]] = '*' after the ith second. The password is said to be irrecoverable when the number of substrings of the password containing at least one malicious character '*' becomes greater than or equal to m. In order to estimate the threat posed by the virus, the team wishes to find the minimum time after which the password becomes irrecoverable. Note: - If the password is irrecoverable at the start, report 1 as the answer. - A substring of a string s is a contiguous segment of that string. Example: There is a password of length n = 5, password = "bcced". The 1-based indices where characters will be replaced: attackOrder = [2, 3, 1, 4, 5] The recoverability parameter m = 10. After the 1st second, the password becomes: The 8 substrings that contain at least one malicious character are: ["b*", "b*c", "b*ce", "b*ced", "*", "*c", "*ce", "*ced"] and 8 is less than m. After the 2nd second, the password becomes: The 11 substrings that contain at least one malicious character are: ["b*", "b**", "b**e", "b**ed", "*", "**", "**e", "**ed", "*", "*e", "*ed"] This is greater than or equal to m. After the replacement at second 2, the number of substrings is at least m. The answer is 2. Function Description: Complete the function findMinimumTime in the editor below. findMinimumTime has the following parameters: string password: the initial password int attackOrder[n]: permutation array of integers [1, 2, ..., n], the attack order of the virus int m: the recoverability parameter Returns: int: the minimum time after which the password becomes irrecoverable. Constraints: - 1 ≤ n ≤ 8 * 10^5 - String password consists of lowercase English characters - 1 ≤ attackOrder[i] ≤ n - 0 ≤ m ≤ n * (n + 1) / 2 Input Format For Custom Testing Sample Case 0 Sample Input For Custom Testing: STDIN -- abc 3 1 2 3 FUNCTION password = "abc" attackOrder[] size n = 3 attackOrder = [1, 2, 3]

Asked in: AMAZON

Image of the Question

Question Image Question Image Question Image

All Testcases Passed ✔



Passcode Image

Solution


def findMinimumTime(password, attackOrder, m):
    # Write your code here
    ans =  1
    n = len(password)
// ... rest of solution available after purchase

🔒 Please login to view the solution

Explanation


```
To solve this problem, you need to understand how the password is transformed over time and how the number of substrings containing at least one malicious character '*' evolves as the virus attacks.

---

### Step 1: Understand the problem setting and key definitions

- You have a password string of length n.
- The virus attacks the password one character at a time, according to a given order attackOrder (a permutation of [1..n]).
- At the ith second, the character at position attackOrder[i] (1-based indexing) is replaced by '*'.
- After each replacement, count how many substrings of the updated password contain at least one '*'.
- The password becomes irrecoverable once the count of such substrings is at least m.
- Your goal is to find the minimum time (i.e., smallest i) such that the password becomes irrecoverable.

---

### Step 2: Analyzing the effect of malicious characters on substrings

First, consider what it means for a substring to contain at least one '*'. Such substrings are any contiguous segments of the password that include at least one attacked character.

At the start (before any attack), there are zero '*' characters, so no substrings with '*'.

As characters get replaced by '*', more substrings become "infected."

---

### Step 3: Total number of substrings and complementary counting

The total number of substrings in a string of length n is:

total_substrings = n * (n + 1) / 2

The problem involves counting substrings that contain '*'. It might be easier to think about the complementary set: substrings that contain no '*' at all (i.e., only original characters).

- If you know the number of substrings with no '*', then:

substrings_with_star = total_substrings - substrings_without_star

This complementary approach can be more efficient than enumerating all substrings explicitly.

---

### Step 4: Representing the password after attacks as segments of normal characters

After some characters are replaced by '*', the password splits into several segments of contiguous normal characters (i.e., characters not replaced by '*') separated by '*'.

For example, if the password length is 10 and '*' appear at positions 3 and 7, the segments of normal characters might be:

- positions 1 to 2 (length 2)
- positions 4 to 6 (length 3)
- positions 8 to 10 (length 3)

---

### Step 5: Counting substrings without '*'

For each segment of length L, the number of substrings without any '*' inside that segment is:

substrings_in_segment = L * (L + 1) / 2

Since these segments are disjoint and substrings cannot cross a '*', the total number of substrings without '*' is the sum over all segments of:

sum(L_i * (L_i + 1) / 2)

---

### Step 6: Update segments efficiently as '*' characters are added

Initially, when there are no '*', the entire password is one segment of length n, and substrings_without_star = total_substrings.

As '*' are introduced (one per second, at position attackOrder[i]):

- The segment that contained the attacked position breaks into two smaller segments (to the left and right of the attacked position).
- For example, if a segment covers positions [start, end] and the attack hits position p (start ≤ p ≤ end):
- The segment is split into at most two segments:
- [start, p-1] (if p > start)
- [p+1, end] (if p < end)
- Remove the old segment's substring count and add counts for the new segments formed.

This process helps maintain the count of substrings_without_star after each attack without recalculating everything from scratch.

---

### Step 7: Checking if the number of substrings with '*' meets or exceeds m

After each attack (each second):

- Calculate:

substrings_with_star = total_substrings - substrings_without_star

- If substrings_with_star ≥ m, then the password is irrecoverable at this time.

Return this time as the minimum time when the password becomes irrecoverable.

---

### Step 8: Algorithm efficiency considerations

- The number of attacks n can be large (up to 8 * 10^5), so the approach must be efficient.
- Use a data structure to quickly find and update segments containing the attacked position.
- One option is to keep track of segments in a balanced tree or interval tree, enabling efficient segment splitting and sum updates.
- This data structure supports:
- Finding which segment contains a given position in O(log n) time.
- Removing a segment and adding new smaller segments after splitting in O(log n) time.
- Update the running sum of substrings_without_star accordingly.

---

### Step 9: Edge cases and initial conditions

- If m = 0, then the password is irrecoverable at time 1 because zero substrings with '*' is already ≥ m (which is 0).
- If the password is initially irrecoverable (e.g., m = 1 and password has no '*', so no substrings with '*'), the problem states to return 1 immediately.
- Handle the case when all characters get replaced, resulting in substrings_without_star = 0, so substrings_with_star = total_substrings.

---

### Summary of the approach

1. Compute total_substrings = n * (n + 1) / 2.
2. Initialize segments with one segment: [1, n], substrings_without_star = total_substrings.
3. Iterate over attackOrder from i = 1 to n:
- Find the segment containing attackOrder[i].
- Remove substrings contributed by that segment from substrings_without_star.
- Split the segment into up to two new segments excluding the attacked position.
- Add substrings contributed by new segments back to substrings_without_star.
- Compute substrings_with_star = total_substrings - substrings_without_star.
- If substrings_with_star ≥ m, return i.
4. If no such time found, return n (all replaced).

This strategy efficiently tracks how substrings without '*' decrease over time, enabling quick calculation of when substrings containing '*' reach or exceed m.
```


Related Questions