【貪心 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章