Swift - LeetCode - 赎金信

·  阅读 511

我正在参加「掘金·启航计划」

题目

给你两个字符串:ransomNotemagazine,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true;否则返回 false

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

  • 输入: ransomNote = "a", magazine = "b"
  • 输出: false

示例 2:

  • 输入: ransomNote = "aa", magazine = "ab"
  • 输出: false

示例 3:

  • 输入: ransomNote = "aa", magazine = "aab"
  • 输出: true

方法一:字符统计

思路及解法

题目要求使用字符串 magazine\textit{magazine} 中的字符来构建新的字符串 ransomNote\textit{ransomNote},且ransomNote\textit{ransomNote} 中的每个字符只能使用一次,只需要满足字符串 magazine\textit{magazine} 中的每个英文字母 (’a’-’z’)(\texttt{'a'-'z'}) 的统计次数都大于等于 ransomNote\textit{ransomNote} 中相同字母的统计次数即可。

  • 如果字符串 magazine\textit{magazine} 的长度小于字符串 ransomNote\textit{ransomNote} 的长度,则我们可以肯定 magazine\textit{magazine} 无法构成 ransomNote\textit{ransomNote},此时直接返回 false\textit{false}

  • 首先统计 magazine\textit{magazine} 中每个英文字母 aa 的次数 cnt[a]\textit{cnt}[a],再遍历统计 ransomNote\textit{ransomNote} 中每个英文字母的次数,如果发现 ransomNote\textit{ransomNote} 中存在某个英文字母 cc 的统计次数大于 magazine\textit{magazine} 中该字母统计次数 cnt[c]\textit{cnt}[c],则此时我们直接返回 false\textit{false}

代码

class Solution {
    func canConstruct(_ ransomNote: String, _ magazine: String) -> Bool {
        if ransomNote.count > magazine.count {
            return false
        }
        
        var cnt: [Int] = Array.init(repeating: 0, count: 26)
        let zCh: Character = "a"
        for ch: Character in magazine {
            cnt[Int(ch.asciiValue! - zCh.asciiValue!)] += 1
        }
        
        for ch: Character in ransomNote {
            cnt[Int(ch.asciiValue! - zCh.asciiValue!)] -= 1
            if cnt[Int(ch.asciiValue! - zCh.asciiValue!)] < 0 {
                return false
            }
        }
        return true
    }
}
复制代码

复杂度分析

  • 时间复杂度:O(m+n)O(m + n),其中 mm 是字符串 ransomNote\textit{ransomNote} 的长度,nn 是字符串 magazine\textit{magazine} 的长度,我们只需要遍历两个字符一次即可。

  • 空间复杂度:O(S)O(∣S∣)SS 是字符集,这道题中 SS 为全部小写英语字母,因此 S=26|S| = 26

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改