【贪心 dw】B032_检查一个字符串是否可以打破另一个字符串(田忌赛马思想)

一、描述

Given two strings: s1 and s2 with the same size, check if some permutation of string s1 can break some permutation of string s2 or vice-versa (in other words s2 can break s1).

A string x can break string y (both of size n) if x[i] >= y[i] (in alphabetical order) for all i between 0 and n-1.

Input: s1 = "abc", s2 = "xya"
Output: true
Explanation: "ayx" is a permutation of s2="xya" 
which can break to string "abc" which is a permutation of s1="abc"

Constraints:

  • s1.length == n
  • s2.length == n
  • 1 <= n <= 10^5
  • All strings consist of lowercase English letters.

方法一:贪心

一开始的想法:

  • 排序,原因是想到了田忌赛马,要让 s2 的所有字符都大于 s1,我很自然想到用数值小的抵消你数值小的。
  • 反正法:如果 s2 的第一小没有去抵消 s1,而是用了一个数值较大的字符取抵消 s1 中最小的,那么较小的那个将有可能打不过 s1 的剩余字符。

WA 了一次: 原因是大小是相对的,如果你参照物是 s1,那么你只能对比 s2,不能在同一个维度里面的两个物体作为参照物或被参照物。

public boolean checkIfCanBreak(String S1, String S2) {
    char[] s1 = S1.toCharArray(), s2 = S2.toCharArray();
    Arrays.sort(s1);Arrays.sort(s2);
    int len1 = 0, len2 = 0, N = s1.length;
    
    for (int i = 0; i < N; i++) {
        if (s1[i] >= s2[i]) len1++;
        if (s1[i] <= s2[i]) len2++;    
    }
    return len1 == N || len2 == N;
}

更正思路:

public boolean checkIfCanBreak(String S1, String S2) {
    char[] s1 = S1.toCharArray(), s2 = S2.toCharArray();
    Arrays.sort(s1);Arrays.sort(s2);
    
    int N = s1.length, len1 = 0, len2 = 0;
    for (int i = 0; i < N; i++) if (s1[i] >= s2[i])
        len1++;
    }
    for (int i = 0; i < N; i++) {if (s1[i] <= s2[i])
        len2++;
    }
    return len1 == N || len2 == N;
}

复杂度分析

  • 时间复杂度:O(NlogN)O(NlogN)
  • 空间复杂度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章