zoukankan      html  css  js  c++  java
  • [LeetCode 1585] Check If String Is Transformable With Substring Sort Operations

    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'.

    Solution 1.

    Since we can only sort any substring in ascending order, when s[i] != t[i], if the next available character t[i] in s is at index j(j > i), then it must be true that all the characters in between index i + 1 and j - 1 are bigger than t[i]. Otherwise, it'd be impossible to change s[i] to t[i]. Using this observation, we derive the following greedy algorithm.

     

    1. store all digits' index in order for start string s. 

    2. keep track of current arrangement count for all digits 0 to 9 for target string t. 

    3. loop over t from left to right, and do the following checks:

    a. for the current character C in t, check if we've already used all available C from s. If so, it means t has more C than s, s and t are not anagram, return false;

    b. for characters smaller than C, check if their next available indices are after the next available C's index. If not, it means there is at least one smaller character before the next available C, C can never be swapped to the current t's position, return false.

    c. if all checks for each position pass, return true.

     

    Both the runtime and space complexity is O(N).

    class Solution {
        public boolean isTransformable(String s, String t) {
            int n = s.length();
            List<Integer>[] sIdx = new List[10];
            for(int i = 0; i < 10; i++) {
                sIdx[i] = new ArrayList<>();
            }
            for(int i = 0; i < n; i++){
                sIdx[s.charAt(i) - '0'].add(i);
            }
            int[] tCnt = new int[10];
            for(int i = 0; i < n; i++) {
                int d = t.charAt(i) - '0';
                if(tCnt[d] >= sIdx[d].size()) {
                    return false;
                }
                for(int j = 0; j < d; j++) {
                    if(tCnt[j] < sIdx[j].size() && sIdx[j].get(tCnt[j]) < sIdx[d].get(tCnt[d])) {
                        return false;
                    }
                }
                tCnt[d]++;
            }
            return true;
        }
    }

    Solution 2.

    There is another elegant O(N) solution.  The key idea is that when checking each digit in s from left to right, we map each digit to its correct position in t. At position i, if s[i] is mapped to position j in t, then we know for all positions > i with bigger digits than s[i],  the furthest left they can go is j + 1 as they can not go pass left of s[i]'s mapped position j. So we create the mapping of all digits from s to t, then check if each digits in s meet this left bound condition. Each time we confirm a mapping at a position, we also update the bigger digits' left bound constraints.

    class Solution {
        public boolean isTransformable(String s, String t) {
            int n = s.length();
            Deque<Integer>[] idx = new ArrayDeque[10];
            //idx[i]: digit i's index in ascending order in string t
            for(int i = 0; i < 10; i++) idx[i] = new ArrayDeque<>();
            for(int i = 0; i < n; i++) {
                idx[t.charAt(i) - '0'].addLast(i);
            }
            //mapTo[i]: mapping from position i in s to s[i]'s correct position in t. 
            int[] mapTo = new int[n];
            for(int i = 0; i < n; i++) {
                int d = s.charAt(i) - '0';
                //if the current digit can not be mapped to t, s and t are not anagrams
                if(idx[d].size() == 0) {
                    return false;
                }
                mapTo[i] = idx[d].pollFirst();
            }
            //lBound[i]: the leftMost position(exclusive) that digit i can appear in string t 
            int[] lBound = new int[10];
            for(int i = 0; i < n; i++) {
                //d: current digit in s
                int d = s.charAt(i) - '0';
                //mapTo[i]: current digit's mapped position in t, it can not go to the left of lBound[d]
                if(mapTo[i] < lBound[d]) {
                    return false;
                }
                //current digit may further tighten future bigger digits' leftMost bound, they can not go to
                //the left of mapTo[i] as mapTo[i] represents the furthest right position for digit d int t,
                //all future > d digits can not go pass left of this position
                for(int j = d + 1; j < 10; j++) {
                    lBound[j] = Math.max(lBound[j], mapTo[i]);
                }
            }
            return true;
        }
    }
     
     
  • 相关阅读:
    Linux mysql 联表查询
    Linux firewalld使用教程+rhce课程实验
    Linux 常用端口
    Linux redhat 7 进入单用户模式
    Linux 子网掩码计算, 二进制十进制互相转换
    Linux 网络配置文件解析
    P1678 烦恼的高考志愿(二分)
    P1563 玩具谜题(简单模拟)
    P1553 数字反转(升级版)(模拟)
    P2690 接苹果 (DP)
  • 原文地址:https://www.cnblogs.com/lz87/p/13670941.html
Copyright © 2011-2022 走看看