Formatted question description: https://leetcode.ca/all/1585.html

1585. Check If String Is Transformable With Substring Sort Operations (Hard)

Given two strings s and t, you want to transform string s into string t using the following operation any number of times:

  • Choose a non-empty substring in s and sort it in-place so the characters are in ascending order.

For example, applying the operation on the underlined substring in "14234" results in "12344".

Return true if it is possible to transform string s into string t. Otherwise, return false.

A substring is a contiguous sequence of characters within a string.

 

Example 1:

Input: s = "84532", t = "34852"
Output: true
Explanation: You can transform s into t using the following sort operations:
"84532" (from index 2 to 3) -> "84352"
"84352" (from index 0 to 2) -> "34852"

Example 2:

Input: s = "34521", t = "23415"
Output: true
Explanation: You can transform s into t using the following sort operations:
"34521" -> "23451"
"23451" -> "23415"

Example 3:

Input: s = "12345", t = "12435"
Output: false

Example 4:

Input: s = "1", t = "2"
Output: false

 

Constraints:

  • s.length == t.length
  • 1 <= s.length <= 105
  • s and t only contain digits from '0' to '9'.

Related Topics:
String, Greedy

Solution 1. Greedy

// OJ: https://leetcode.com/problems/check-if-string-is-transformable-with-substring-sort-operations/

// Time: O(N)
// Space: O(N)
// Ref: https://youtu.be/Pkd3FampKBk
class Solution {
public:
    bool isTransformable(string s, string t) {
        queue<int> q[10];
        for (int i = 0; i < s.size(); ++i) q[s[i] - '0'].push(i);
        for (int i = 0; i < t.size(); ++i) {
            int d = t[i] - '0';
            if (q[d].empty()) return false;
            for (int j = 0; j < d; ++j) {
                if (q[j].size() && q[j].front() < q[d].front()) return false;
            }
            q[d].pop();
        }
        return true;
    }
};

Java

class Solution {
    public boolean isTransformable(String s, String t) {
        int length = s.length();
        int[] counts = new int[10];
        for (int i = 0; i < length; i++)
            counts[s.charAt(i) - '0']++;
        for (int i = 0; i < length; i++)
            counts[t.charAt(i) - '0']--;
        for (int i = 0; i < 10; i++) {
            if (counts[i] != 0)
                return false;
        }
        List[] locations = new List[10];
        for (int i = 0; i < 10; i++)
            locations[i] = new ArrayList<Integer>();
        for (int i = length - 1; i >= 0; i--)
            locations[s.charAt(i) - '0'].add(i);
        for (int i = 0; i < length; i++) {
            int digit = t.charAt(i) - '0';
            List<Integer> indices = locations[digit];
            int next = indices.remove(indices.size() - 1);
            for (int j = 0; j < digit; j++) {
                List<Integer> listJ = locations[j];
                int size = listJ.size();
                if (size > 0 && listJ.get(size - 1) < next)
                    return false;
            }
        }
        return true;
    }
}

All Problems

All Solutions