mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-13 14:10:38 +08:00
Update 0763.划分字母区间.md
This commit is contained in:
@ -231,83 +231,56 @@ class Solution{
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Python
|
### Python
|
||||||
|
贪心(版本一)
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def partitionLabels(self, s: str) -> List[int]:
|
def partitionLabels(self, s: str) -> List[int]:
|
||||||
hash = [0] * 26
|
last_occurrence = {} # 存储每个字符最后出现的位置
|
||||||
for i in range(len(s)):
|
for i, ch in enumerate(s):
|
||||||
hash[ord(s[i]) - ord('a')] = i
|
last_occurrence[ch] = i
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
left = 0
|
start = 0
|
||||||
right = 0
|
end = 0
|
||||||
for i in range(len(s)):
|
for i, ch in enumerate(s):
|
||||||
right = max(right, hash[ord(s[i]) - ord('a')])
|
end = max(end, last_occurrence[ch]) # 找到当前字符出现的最远位置
|
||||||
if i == right:
|
if i == end: # 如果当前位置是最远位置,表示可以分割出一个区间
|
||||||
result.append(right - left + 1)
|
result.append(end - start + 1)
|
||||||
left = i + 1
|
start = i + 1
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# 解法二(不相交区间法)
|
```
|
||||||
|
贪心(版本二)与452.用最少数量的箭引爆气球 (opens new window)、435.无重叠区间 (opens new window)相同的思路。
|
||||||
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def partitionLabels(self, s: str) -> List[int]:
|
def countLabels(self, s):
|
||||||
# 记录每个字母出现的区间
|
# 初始化一个长度为26的区间列表,初始值为负无穷
|
||||||
def getBord(s):
|
hash = [[float('-inf'), float('-inf')] for _ in range(26)]
|
||||||
hash = [[-float('inf')] * 2 for _ in range(26)]
|
hash_filter = []
|
||||||
for i in range(len(s)):
|
for i in range(len(s)):
|
||||||
if hash[ord(s[i]) - ord('a')][0] == -float('inf'):
|
if hash[ord(s[i]) - ord('a')][0] == float('-inf'):
|
||||||
hash[ord(s[i]) - ord('a')][0] = i
|
hash[ord(s[i]) - ord('a')][0] = i
|
||||||
hash[ord(s[i]) - ord('a')][1] = i
|
hash[ord(s[i]) - ord('a')][1] = i
|
||||||
# 去除字符串中未出现的字母所占用区间
|
|
||||||
hash_filter = []
|
|
||||||
for item in hash:
|
|
||||||
if item[0] != -float('inf'): hash_filter.append(item)
|
|
||||||
return hash_filter
|
|
||||||
|
|
||||||
# 得到无重叠区间题意中的输入样例格式:区间列表
|
|
||||||
hash = getBord(s)
|
|
||||||
# 按照左边界从小到大排序
|
|
||||||
hash.sort(key= lambda x: x[0])
|
|
||||||
res = []
|
|
||||||
left = 0
|
|
||||||
# 记录最大右边界
|
|
||||||
right = hash[0][1]
|
|
||||||
for i in range(len(hash)):
|
for i in range(len(hash)):
|
||||||
# 一旦下一区间左边界大于当前右边界,即可认为出现分割点
|
if hash[i][0] != float('-inf'):
|
||||||
if hash[i][0] > right:
|
hash_filter.append(hash[i])
|
||||||
res.append(right - left + 1)
|
return hash_filter
|
||||||
left = hash[i][0]
|
|
||||||
# 实时更新最大右边界
|
def partitionLabels(self, s):
|
||||||
right = max(right, hash[i][1])
|
res = []
|
||||||
# 最右侧区间(字符串长度为1时的特殊情况也包含于其中)
|
hash = self.countLabels(s)
|
||||||
res.append(right - left + 1)
|
hash.sort(key=lambda x: x[0]) # 按左边界从小到大排序
|
||||||
|
rightBoard = hash[0][1] # 记录最大右边界
|
||||||
|
leftBoard = 0
|
||||||
|
for i in range(1, len(hash)):
|
||||||
|
if hash[i][0] > rightBoard: # 出现分割点
|
||||||
|
res.append(rightBoard - leftBoard + 1)
|
||||||
|
leftBoard = hash[i][0]
|
||||||
|
rightBoard = max(rightBoard, hash[i][1])
|
||||||
|
res.append(rightBoard - leftBoard + 1) # 最右端
|
||||||
return res
|
return res
|
||||||
|
|
||||||
# 解法三:区间合并法 (结合下一题 56. Merge Intervals 的写法)
|
|
||||||
class Solution: #
|
|
||||||
def partitionLabels(self, s: str) -> List[int]:
|
|
||||||
aaa = list(set(s))
|
|
||||||
#aaa.sort()
|
|
||||||
bbb = list(s)
|
|
||||||
ccc = []
|
|
||||||
for i in reversed(bbb):
|
|
||||||
ccc.append(i)
|
|
||||||
intervals = []
|
|
||||||
for i in range(len(aaa)):
|
|
||||||
intervals.append([bbb.index(aaa[i]),len(bbb)-ccc.index(aaa[i])-1])
|
|
||||||
# 先求出各个字母的存在区间,之后利用区间合并方法得出所有不相邻的最大区间。
|
|
||||||
intervals.sort(key = lambda x:x[0])
|
|
||||||
newinterval = []
|
|
||||||
left, right = intervals[0][0], intervals[0][1]
|
|
||||||
for i in range(1,len(intervals)):
|
|
||||||
if intervals[i][0] in range(left, right+1):
|
|
||||||
right = max(intervals[i][1],intervals[i-1][1],right)
|
|
||||||
left = min(intervals[i-1][0],left)
|
|
||||||
else:
|
|
||||||
newinterval.append(right-left+1)
|
|
||||||
left = intervals[i][0]
|
|
||||||
right = intervals[i][1]
|
|
||||||
newinterval.append(right-left+1)
|
|
||||||
return newinterval
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
Reference in New Issue
Block a user