[Swift]LeetCode777. 在LR字符串中交换相邻字符 | Swap Adjacent in LR String
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10541711.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
In a string composed of 'L'
, 'R'
, and 'X'
characters, like "RXXLRXRXL"
, a move consists of either replacing one occurrence of "XL"
with "LX"
, or replacing one occurrence of "RX"
with "XR"
. Given the starting string start
and the ending string end
, return True
if and only if there exists a sequence of moves to transform one string to the other.
Example:
Input: start = "RXXLRXRXL", end = "XRLXXRRLX" Output: True Explanation: We can transform start to end following these steps: RXXLRXRXL -> XRXLRXRXL -> XRLXRXRXL -> XRLXXRRXL -> XRLXXRRLX
Note:
1 <= len(start) = len(end) <= 10000
.- Both start and end will only consist of characters in
{'L', 'R', 'X'}
.
在一个由 'L'
, 'R'
和 'X'
三个字符组成的字符串(例如"RXXLRXRXL"
)中进行移动操作。一次移动操作指用一个"LX"
替换一个"XL"
,或者用一个"XR"
替换一个"RX"
。现给定起始字符串start
和结束字符串end
,请编写代码,当且仅当存在一系列移动操作使得start
可以转换成end
时, 返回True
。
示例 :
输入: start = "RXXLRXRXL", end = "XRLXXRRLX" 输出: True 解释: 我们可以通过以下几步将start转换成end: RXXLRXRXL -> XRXLRXRXL -> XRLXRXRXL -> XRLXXRRXL -> XRLXXRRLX
注意:
1 <= len(start) = len(end) <= 10000
。start
和end
中的字符串仅限于'L'
,'R'
和'X'
。
1 class Solution { 2 func canTransform(_ start: String, _ end: String) -> Bool { 3 var start = Array(start) 4 var end = Array(end) 5 var n:Int = start.count 6 var cntL:Int = 0 7 var cntR:Int = 0 8 for i in 0..<n 9 { 10 if start[i] == "R" {cntR += 1} 11 if end[i] == "L" {cntL += 1} 12 if start[i] == "L" {cntL -= 1} 13 if end[i] == "R" {cntR -= 1} 14 if cntL < 0 || cntR < 0 || cntL * cntR != 0 15 { 16 return false 17 } 18 } 19 return cntL == 0 && cntR == 0 20 } 21 }
68ms
1 class Solution { 2 func canTransform(_ start: String, _ end: String) -> Bool { 3 let cs = Array(start) 4 let ce = Array(end) 5 let ts = String(cs.filter{ $0 != "X" } ) 6 let te = String(ce.filter{ $0 != "X" } ) 7 8 guard ts == te else { return false } 9 10 var sr = [Int]() 11 var sl = [Int]() 12 13 for (i, char) in cs.enumerated() { 14 if char == "R" { 15 sr.append(i) 16 } else if char == "L" { 17 sl.append(i) 18 } 19 } 20 21 var rCount = 0 22 var lCount = 0 23 24 for (i, char) in ce.enumerated() { 25 if char == "R" { 26 if sr[rCount] > i { 27 return false 28 } else { 29 rCount += 1 30 } 31 } else if char == "L" { 32 if sl[lCount] < i { 33 return false 34 } else { 35 lCount += 1 36 } 37 } 38 } 39 40 return true 41 } 42 }
96ms
1 class Solution { 2 func compare(_ start: String, _ end: String) -> Bool { 3 var rs1 = 0 4 var ls1 = 0 5 var xs1 = 0 6 var rs2 = 0 7 var ls2 = 0 8 var xs2 = 0 9 for i in start.indices { 10 switch start[i] { 11 case "R": 12 rs1 += 1 13 case "L": 14 ls1 += 1 15 case "X": 16 xs1 += 1 17 default: 18 break 19 } 20 switch end[i] { 21 case "R": 22 rs2 += 1 23 case "L": 24 ls2 += 1 25 case "X": 26 xs2 += 1 27 default: 28 break 29 } 30 } 31 return rs1 == rs2 && ls1 == ls2 && xs1 == xs2 32 } 33 34 func canTransform(_ start: String, _ end: String) -> Bool { 35 var rs = [String.Index]() 36 var ls = [String.Index]() 37 for (i, ch) in zip(start.indices, start) { 38 if ch == "R" { 39 rs.append(i) 40 } else if ch == "L" { 41 ls.append(i) 42 } 43 } 44 rs.reverse() 45 ls.reverse() 46 47 if !compare(start, end) { 48 return false 49 } 50 51 for (i, ch) in zip(end.indices, end) { 52 if ch == "R" { 53 if let nextRIdx = rs.last, nextRIdx <= i { 54 if let nextLIdx = ls.last { 55 if nextLIdx < nextRIdx { 56 // impossible to move R through L 57 return false 58 } else { 59 rs.removeLast() 60 } 61 } else { 62 rs.removeLast() 63 } 64 } else { 65 return false 66 } 67 } else if ch == "L" { 68 if let nextLIdx = ls.last, nextLIdx >= i { 69 if let nextRIdx = rs.last { 70 if nextRIdx < nextLIdx { 71 // impossible to move L through R 72 return false 73 } else { 74 ls.removeLast() 75 } 76 } else { 77 ls.removeLast() 78 } 79 } else { 80 return false 81 } 82 } 83 } 84 return true 85 } 86 }
104ms
1 class Solution { 2 func canTransform(_ start: String, _ end: String) -> Bool { 3 guard start.count >= 1 && start.count <= 10000 && end.count >= 1 && end.count <= 10000 else { 4 return false 5 } 6 let startChars = Array(start), endChars = Array(end) 7 var startInfos = [(Character, Int)](), endInfos = [(Character, Int)]() 8 for (index, char) in startChars.enumerated() { 9 if char == "L" || char == "R" { 10 startInfos.append((char, index)) 11 } else if char != "X" { 12 return false 13 } 14 } 15 for (index, char) in endChars.enumerated() { 16 if char == "L" || char == "R" { 17 endInfos.append((char, index)) 18 } else if char != "X" { 19 return false 20 } 21 } 22 let startInfosChars = startInfos.map { 23 $0.0 24 } 25 let endInfosChars = endInfos.map { 26 $0.0 27 } 28 guard startInfosChars == endInfosChars else { 29 return false 30 } 31 for (index, startInfo) in startInfos.enumerated() { 32 let endInfo = endInfos[index] 33 if startInfo.0 == "L" { 34 guard startInfo.1 >= endInfo.1 else { 35 return false 36 } 37 } else { 38 guard startInfo.1 <= endInfo.1 else { 39 return false 40 } 41 } 42 } 43 return true 44 } 45 }