【LeetCode】【Math】DI string match
题目:
给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length。
返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i = 0, ..., N-1,都有:
如果 S[i] == "I",那么 A[i] < A[i+1]
如果 S[i] == "D",那么 A[i] > A[i+1]
如果 S[i] == "D",那么 A[i] > A[i+1]
例如:
输入:“IDID”
输出:[0,4,1,3,2]
输入:“III”
输出:[0,1,2,3]
输入:“DDI”
输出:[3,2,0,1]
注意:
-
1 <= S.length <= 10000
-
S仅包含字符I或D。
虽然题目是string match,直译为字符串匹配,但我认为题目的意思更倾向于字符串构建。
解法:
因为没看懂题目,所以是参考答案写的。
class Solution: def diStringMatch(self, S: str) -> List[int]: A = [] left,right= 0,len(S) for i in S: if i == "I": A.append(left) left += 1 if i == "D": A.append(right) right -= 1 return A+[left]
Runtime: 64 ms, faster than 79.49% of Python3 online submissions for DI String Match.
Memory Usage: 14.9 MB, less than 33.89% of Python3 online submissions for DI String Match.
思路:在本题中,元素是什么并不重要,只要它们是不同且有序便可,所以:
当看到“ I”时,最安全的选择是放入最小(最左边)的数字,因此它将始终增加,即S[0]=="I",第一个元素可取最小的0;
当看到“ D”时,最安全的选择是放入最大(最右边)的数字,因此该数字始终会减少,即如果S[0]=="D",第一个元素可取最大的len(S)
所以令left,right = 0,len(S)
return A+[left] 和 return A+ [right]的结果是一样的。因为最后一个数是right==left
更精简的写法
class Solution: def diStringMatch(self, S: str) -> List[int]: l, r, arr = 0, len(S), [] for s in S: arr.append(l if s == "I" else r) l, r = l + (s == "I"), r - (s == "D") return arr + [l]
Runtime: 68 ms, faster than 59.91% of Python3 online submissions for DI String Match.
Memory Usage: 14.8 MB, less than 64.10% of Python3 online submissions for DI String Match.
学习:判断语句的另一种写法
解法2:
def diStringMatch(self, S): left = right = 0 res = [0] for i in S: if i == "I": right += 1 res.append(right) else: left -= 1 res.append(left) return [i - left for i in res]
Runtime: 72 ms, faster than 41.18% of Python3 online submissions for DI String Match.
Memory Usage: 15.1 MB, less than 6.28% of Python3 online submissions for DI String Match.
思路:以第一个数为原点(0),如果看到“ I”,则+1; 否则-1。最后将所有的数都挪到正数。(这个方法很形象

浙公网安备 33010602011771号