1. 程式人生 > 實用技巧 >夢想從這裡開始,退一步海闊天空

夢想從這裡開始,退一步海闊天空

字串 S 由小寫字母組成。我們要把這個字串劃分為儘可能多的片段,同一個字母只會出現在其中的一個片段。返回一個表示每個字串片段的長度的列表。

示例 1:

輸入:S = "ababcbacadefegdehijhklij"
輸出:[9,7,8]
解釋:
劃分結果為 "ababcbaca", "defegde", "hijhklij"。
每個字母最多出現在一個片段中。
像 "ababcbacadefegde", "hijhklij" 的劃分是錯誤的,因為劃分的片段數較少。

提示:

S的長度在[1, 500]之間。
S只包含小寫字母 'a' 到 'z' 。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/partition-labels

時間複雜度:O(n)

空間複雜度:需要一個額外26個空間

class Solution {
    public List<Integer> partitionLabels(String S) {

        //首先迴圈一遍,記錄下每個字母的索引位置,索引位置可能有多個,只需要記錄第一個就行了
        int [] letterArray = new int[26]; //初始化陣列為-1
        for(int i = 0; i < 26; i++){
            letterArray[i] = -1;
        }
        
int strLength = S.length(); for(int i=strLength-1; i >=0; i--){ int index = S.charAt(i) - 'a'; if(letterArray[index] == -1){ letterArray[index] = i; } } //得到一個數組,每個字元的最開始出現的位置 //第二次遍歷 List<Integer> result = new
ArrayList<>(); int preEndIndex = 0; //標識這個字串開始的索引 int maxIndex = 0; //標識這個字串中最大的索引 for(int i = 0 ; i < strLength; i++){ int tempMin = letterArray[S.charAt(i) - 'a']; maxIndex = Math.max(tempMin,maxIndex); if(tempMin == i && maxIndex == i){ //說明當前節點可以單獨成為字串 result.add(i - preEndIndex + 1); preEndIndex = i+1; } } //依次找每個字元的最開始出現的位置,如果跟當前索引位置相同,則記錄長度 長度 = 索引開始 - 索引結束 + 1 return result; } }