1. 程式人生 > >LeetCode_003 Longest Substring Without Repeating Characters

LeetCode_003 Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke"is a subsequence and not a substring.

************************************************************************************************************************************

 

這裡我實在很無奈,看著排名靠前的那些程式碼,思路一團糟,只能找點可以理解的給消化掉:

 

解決方案與思路分析*3:

單獨開闢記憶體空間來儲存子串*temp,而*(length+i)表示最外層迴圈每次對應的子串長度;

首先控制最外層迴圈所執行的次數為count,內部子序列迴圈次數依舊是count,起始值為i+1;

在內層迴圈過程中需要對子串進行判斷(是否和index大於i的資料相等),不相等*(length+i)++,否則跳出兩個迴圈。

int lengthOfLongestSubstring(char* s) {
    
    int count =0;
    while(s[count]!='\0')
    {
        count++;
    }
    char *temp = (char *)malloc(sizeof(char)*count);
    int *length = (int *)malloc(sizeof(int)*count);
    for(int i=0;i<count;i++)
    {
        length[i] = 1;
        temp[0] = s[i];
        for(int j=i+1;j<count;j++)
        {
            bool flag =false;
            for(int k=j-1;k>=i;k--)
            {
                if(s[j]==s[k])
                {
                    break;
                }
                else if(s[j]!=s[k]&&k==i)
                {
                    temp[j] = s[j];
                    length[i]++;
                    
                    flag = true;
                }  
            }   
            if(!flag)
            {
                break;
            }
        }
    }
    
    int max_length =length[0];
    for(int i=0;i<count-1;i++)
    {
        if(max_length<=length[i+1])
        {
            max_length = length[i+1];
        }
    }
    return max_length;
}

 

 

分析後發現,沒有必要額外儲存子串,刪除後,時間減少為184ms:

*也可以使用strlen()來直接求字串陣列長度,時間上沒有太大差別

 

 

分析了部分其他人的原始碼,發現還可以使用ASCII碼的思想來做:

基本思想:

將每個字元的ASCII碼映作為另一個數組的下標,對該下標的值進行替換;

這樣做可以直接在第二層迴圈中開始進行判斷,而不需要像上面一樣再新增加一個迴圈;

(實際上是增加了空間的消耗來減少了時間的消耗)

​​​​​​int lengthOfLongestSubstring(char* s) 
{
    int count = strlen(s);
    int *length = (int*)malloc(sizeof(int)*count);
    int ch;
    int ascii_in_s[256];
    for(int i=0;i<256;i++)    //初始化ASCII碼陣列
    {
        ascii_in_s[i] = -1;
    }
    for(int i=0;i<count;i++)    //初始化長度陣列
    {
        length[i]=1;
    }
    for(int i=0;i<count;i++)
    {
        ch = s[i];
        ascii_in_s[ch] = i;
        for(int j =i+1;j<count;j++)
        {
            ch = s[j];
            if(ascii_in_s[ch]==-1)
            {
                ascii_in_s[ch] = j;
                length[i]++;
            }
            else
            {
                break;
            }
        }
       for (int k = 0; k < 256; k++)    //最外層迴圈每進行一次,需要對陣列進行一次初始化
       {
           ascii_in_s[k] = -1; 
       } 
    }
    int max_length =length[0];
    for(int i=0;i<count-1;i++)
    {
        if(max_length<=length[i+1])
        {
            max_length = length[i+1];
        }
    }
    return max_length;
}