1. 程式人生 > >LeetCode初級演算法

LeetCode初級演算法

目錄

1.陣列

2.字串

3.連結串列

4.樹

5.排序和搜尋

6.動態規劃

7.設計問題

8.數學

9.其他


1.陣列

1.1 給定一個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。

不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 O(1) 額外空間的條件下完成。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) 
    {
        int i=!nums.empty();
        for(int n:nums)
        {
            if(n>nums[i-1]) 
            {
                nums[i]=n;
                 i++;
            }
            
        }                        
       return i;
    }
};

1.2  給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。

設計一個演算法來計算你所能獲取的最大利潤。你可以儘可能地完成更多的交易(多次買賣一支股票)。

class Solution {
public:
    int maxProfit(vector<int>& prices) 
    {
        int k=-1;
        vector<int> re_prices;
        for(int m:prices)
        {
            if(m!=k)
            {
                re_prices.push_back(m);
                k=m;
            }
        }
        prices=re_prices;
        int min=-1,max=-1;
        int sum=0;
        if( prices.size()==2) if(prices[1]>prices[0]) sum=prices[1]-prices[0];
        if( prices.size()>=3)
        {
        if(prices[0]<=prices[1]) min=prices[0];   
        for(int i=1;i<prices.size();i++)
        {
           if(prices[i]<prices[i-1] && prices[i]<prices[i+1]) min=prices[i];
           if(prices[i]>prices[i-1] && prices[i]>prices[i+1]) max=prices[i];
           if(prices[i]>prices[i-1] && i==prices.size()-1) max=prices[i];
           if(min!=-1 && max!=-1) 
           {
               sum=sum+max-min;
               min=-1;
               max=-1;
           }
        }
            
        }
        return sum;
    }
};

1.3 給定一個數組,將陣列中的元素向右移動 個位置,其中 是非負數。

class Solution {
public:
    void rotate(vector<int>& nums, int k) 
    {
        vector<int> re_nums;
        k=k%nums.size();
        int seed=nums.size()-k;
        if(seed>0)
        {
        for(int i=seed;i<nums.size();i++)
           re_nums.push_back(nums[i]);
        for(int i=0;i<seed;i++)
           re_nums.push_back(nums[i]);
        nums=re_nums;
        }
    }
};

1.4  給定一個整數陣列,判斷是否存在重複元素。

如果任何值在陣列中出現至少兩次,函式返回 true。如果陣列中每個元素都不相同,則返回 false。

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        int n=nums.size();
        for(int i=0;i<n;i++)
        {
            int count=0;
            for(int j=i+1;j<n;j++)
            {
                if(nums[i]==nums[j]) return true;
            }
        }
        return false;
    }
};

1.5  給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。

       說明: 你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
         int tem[nums.size()]={0};
         for(int i=0;i<nums.size();i++)
         {
             for(int j=0;j<nums.size();j++)
             {
                 if(nums[i]==nums[j]) tem[i]++;
                 if(tem[i]>1) break;
                 if(j==nums.size()-1 && tem[i]==1) return nums[i];
             }
         }                        
    }
};

1.6 給定兩個陣列,編寫一個函式來計算它們的交集。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2)
    {
        vector<int> result;
        if(nums1.size()!=0 && nums2.size()!=0)
        {
        int tem1[nums1.size()]={0};
        int tem2[nums2.size()]={0};
        for(int i=0;i<nums1.size();i++)
        {
            for(int j=i;j<nums1.size();j++)
            {
            if(nums1[i]==nums1[j]) tem1[i]++;
            }
        }
        
        for(int i=0;i<nums2.size();i++)
        {
            for(int j=i;j<nums2.size();j++)
            {
            if(nums2[i]==nums2[j]) tem2[i]++;
            }
        }
        
 for(int i=0;i<nums1.size();i++)
     for(int j=0;j<nums2.size();j++)
         if(nums1[i]==nums2[j] && tem1[i]==tem2[j]) result.push_back(nums1[i]);
        
        }
        
        return result;
     }
};

1.7  給定一個由整數組成的非空陣列所表示的非負整數,在該數的基礎上加一。

最高位數字存放在陣列的首位, 陣列中每個元素只儲存一個數字。

你可以假設除了整數 0 之外,這個整數不會以零開頭

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) 
    {
        int n=digits.size();
        if(digits[n-1]<9)
        {
            digits[n-1]+=1;
            return digits;
        }
        if(digits[n-1]==9)
        {
        int tem=0;
        for(int i=0;i<n;i++,tem++) if(digits[n-1-i]!=9)
        {
            //tem++;
            break;
        }
        if(tem==n)
        {
            vector<int> re(n+1,0);
              re[0]=1;
               digits = re;
        }
         else 
         {
             for(int i=0;i<tem;i++) digits[n-1-i]=0 ;
             digits[n-1-tem]+=1;
         }   
            
            
        }
        return digits;
            
    }
};

1.8 給定一個數組 nums,編寫一個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序

class Solution {
public:
    void moveZeroes(vector<int>& nums) 
    {
      for(int i=0;i<nums.size();i++)
      {
          if(nums[i]==0 && nums[i+1]!=0 && i<nums.size()-1)
          {
              nums[i]=nums[i+1];
              nums[i+1]=0;
              int j=i;
              while(nums[j-1]==0 && j-1>=0)
              {
                  nums[j-1]=nums[j];
                  nums[j]=0;
                  j--;
              }
          }
      }
        
       
    }
};

1.9  給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。

      你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        
        for(int i=0;i<nums.size();i++)
        {
            for(int j=i+1;j<nums.size();j++)
            {
                if((nums[i]+nums[j])==target) 
                {
                    vector<int> result={i,j};
                    return result;
                }
            }
                                              
        }
    }
};

1.10  判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。

  1. 數字 1-9 在每一行只能出現一次。
  2. 數字 1-9 在每一列只能出現一次。
  3. 數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board)
    {
     int tem_row[9][9]={0};
     int tem_col[9][9]={0};
     int tem_nine[9][9]={0};
     vector<vector<char>> re_board(9);
     for(int i=0;i<9;i++)
     {
         for(char m:board[i])
         {
            if(m!='.') 
            {
                int index=m -'0' - 1;
                tem_row[i][index]++;
            }
         }
        for(int m:tem_row[i])
        {
            if(m>1) return false;
        }
         for(int j=0;j<9;j++)
         {
            if((int)board[j][i]!='.') tem_col[i][board[j][i]-'0'-1]++;
         }
        for(int m:tem_col[i])
        {
            if(m>1) return false;  
        }
        
     }
        for(int i=0;i<9;i++)
        {
         for(int j=0;j<9;j++)
         {
         re_board[j/3+3*(i/3)].push_back(board[i][j]);        
         }
        }
        for(int i=0;i<9;i++)
        {
         for(char m:re_board[i])
         {
            if(m!='.') tem_nine[i][m-'0'-1]++;
         }    
        
        for(int m:tem_nine[i])
            if(m>1) return false;
        }
        
        return true;
        
    }
};

1.11  給定一個 × n 的二維矩陣表示一個影象。

        將影象順時針旋轉 90 度。

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) 
    {
        int n=matrix.size();
        if(n>0) 
        {
            for(int i=0;i<n/2;i++)
            {
                for(int j=i;j<n-1-i;j++)
                {
                    int tem=matrix[i][j];
                    matrix[i][j]=matrix[n-1-j][i];
                    matrix[n-1-j][i]=matrix[n-1-i][n-1-j];
                    matrix[n-1-i][n-1-j]=matrix[j][n-1-i];
                    matrix[j][n-1-i]=tem;
                }    
            }
        }
    }
};

2.字串

2.1 編寫一個函式,其作用是將輸入的字串反轉過來。

class Solution {
public:
    string reverseString(string s)
    {
        string re_s(s);
        int n=s.size();
        int index=n-1;
        for(int i=0;i<n;i++)
        {
            re_s[i]=s[index--];
        }
        return re_s;
    }
};

2.2 給定一個 32 位有符號整數,將整數中的數字進行反轉

class Solution {
public:
  int reverse(int x)
  {
      int IN_MAX=2147483647;
      bool is_negative=false;
      if(x<0) 
      {
          is_negative=true;
          x=-x;
      }
      int count_num=0;
      int copy=x;
      while(copy>0)
      {
          count_num++;
          copy=copy/10;
      }
      int sum=0;
      if(count_num<10)
      {
       while(x>0)
        {
          int rem=x%10;
          x=x/10;
          sum=sum*10+rem;
        }
      }
     else 
      {
        while(x>10)
         {
          int rem=x%10;
          x=x/10;
          sum=sum*10+rem;
         }
         if(sum>IN_MAX/10 || (sum==IN_MAX/10 && x>7)) return 0;
         else sum=sum*10+x;
      }
      
      return is_negative?sum*(-1):sum;
  }
   
    
};

2.3 給定一個字串,找到它的第一個不重複的字元,並返回它的索引。如果不存在,則返回 -1。

class Solution {
public:
    int firstUniqChar(string s) 
    {
        int n=s.size();
        if(n==0)return -1;
        int count[n]={0};
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                if(s[i]==s[j])count[i]++;
                if(count[i]==2) break;
            }
            if(count[i]==1) return i;
        }

        return -1;
    }
};

2.4 給定兩個字串 s 和 t ,編寫一個函式來判斷 t 是否是 s 的一個字母異位詞

class Solution {
public:
    bool isAnagram(string s, string t) 
    {
        if(s.size()!=t.size())return false;
        int count_s[26]={0};
        int count_t[26]={0};
        for(int i=0;i<s.size();i++)
        {
            int num_s=s[i]-'a';
            count_s[num_s]++;
            int num_t=t[i]-'a';
            count_t[num_t]++;
        }
        for(int i=0;i<26;i++)
        {
            if(count_s[i]!=count_t[i]) return false;
        }
        
        return true;
        
        
    }
};

2.5 給定一個字串,驗證它是否是迴文串,只考慮字母和數字字元,可以忽略字母的大小寫。

class Solution {
public:
    bool isPalindrome(string s)
    {
        int n=0;
        for(char &m:s)
        {
            if(isalnum(m))
            {
                n+=1;
                if(isalpha(m)) m=tolower(m);
            }
        }
        string s1(n,'a');
        int k=0;
        for(int i=0;i<s.size();i++)
        {
            if(isalnum(s[i])) s1[k++]=s[i];
        }
        string s2(s1);
        for(int i=0;i<n;i++)
        {
            s2[i]=s1[n-1-i];
        }
        if(s1==s2)return true;
        return false;
    }
};

2.6  實現 atoi,將字串轉為整數。

該函式首先根據需要丟棄任意多的空格字元,直到找到第一個非空格字元為止。如果第一個非空字元是正號或負號,選取該符號,並將其與後面儘可能多的連續的數字組合起來,這部分字元即為整數的值。如果第一個非空字元是數字,則直接將其與之後連續的數字字元組合起來,形成整數。

字串可以在形成整數的字元後面包括多餘的字元,這些字元可以被忽略,它們對於函式沒有影響。

當字串中的第一個非空字元序列不是個有效的整數;或字串為空;或字串僅包含空白字元時,則不進行轉換。

若函式不能執行有效的轉換,返回 0。

class Solution {
public:
    int myAtoi(string str) 
    {
        if(str.empty()) return 0;
        int a;
        int index_symbol=-1;
        for(int i=0;i<str.size();i++)
        {
            char m=str[i];
            if(m!=' ')
            {
              if(m=='-')
              {
                  a=-1;
                  index_symbol=i;
              }
              else if(m=='+' || isdigit(m)) 
              {
                  a=1;
                  if(m=='+') index_symbol=i;
              }
              else return 0;
              break;
            }
        }
        if(index_symbol!=-1) 
        {
            if(!isdigit(str[index_symbol+1])) return 0;
        }
        int num_index=-1;
        for(int i=0;i<str.size();i++)
        {
            if(isdigit(str[i]))
            {
                num_index=i;
                break;
            }
        }
        if(num_index==-1) return 0;
        
        string numX;
        for(int i=num_index;i<str.size();i++)
        {
            if(isdigit(str[i]))
            {
                numX+=str[i];
                if(!isdigit(str[i+1])) break;
            }
        }
        
        int nonzero_index=-1;
        for(int i=0;i<numX.size();i++)
        {
            if(numX[i]=='0')continue;
            nonzero_index=i;
            break;
        }
        if(nonzero_index==-1) return 0;
        
        string num;
        for(int i=nonzero_index;i<numX.size();i++)
        {
            num+=numX[i];
        }
        
        int sum=0;
        int n=num.size();
        if(n<10)
        {
           for(int i=0;i<n;i++)
           {
            int tem=num[i]-'0';
            sum=sum*10+tem;
           }
        }
       else if(n>10) 
       {
           if(a==-1)return INT_MIN;
           else sum=INT_MAX;
       } 
       else  
       {
           for(int i=0;i<9;i++)
           {
            int tem=num[i]-'0';
            sum=sum*10+tem;
           }
           if(sum>INT_MAX/10) 
           {
               if(a==1)sum=INT_MAX;
               else return INT_MIN;
           }
           else if(sum<INT_MAX/10) 
           {
               int tem=num[9]-'0';
               sum=sum*10+tem;
           }
           else 
           {
               int tem=num[9]-'0';
               if(tem<=7)
               {
                   int tem=num[9]-'0';
                   sum=sum*10+tem;
               }
               else if(tem==8)
               {
                   if(a==-1) return INT_MIN;
                   else return INT_MAX;
               }
               else 
               {
                   if(a==1)sum=INT_MAX;
                   else return INT_MIN;
               }
           }
       }


        return a*sum;
    }
};

2.7  實現 strStr() 函式。

給定一個 haystack 字串和一個 needle 字串,在 haystack 字串中找出 needle 字串出現的第一個位置 (從0開始)。如果不存在,則返回  -1

class Solution {
public:
    int strStr(string haystack, string needle) 
    {
        if(needle.empty())return 0;
        int n=needle.size();
        char arc=needle[0];
        for(int i=0;i<haystack.size();i++)
        {
            if(haystack[i]==arc)
            {
                string s(n,arc);
                int k=0;
                for(int j=i;j<i+n;j++)
                {
                  s[k++]= haystack[j];
                }
                if(s==needle) return i;
            }
        }
        return -1;
    }
};

2.8 報數序列是一個整數序列,按照其中的整數的順序進行報數,得到下一個數。其前五項如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221

1 被讀作  "one 1"  ("一個一") , 即 11
11 被讀作 "two 1s" ("兩個一"), 即 21
21 被讀作 "one 2",  "one 1" ("一個二" ,  "一個一") , 即 1211

給定一個正整數 n(1 ≤ n ≤ 30),輸出報數序列的第 n 項。

注意:整數順序將表示為一個字串

class Solution {
public:
    string countAndSay(int n) 
    {
        string a="1";
        string tem;
        for(int i=1;i<n;i++)
        {
            int t=0;
            while(t<a.size())
            {
                int value=1;
                while(a[t]==a[t+1])
                {
                    value++;
                    t++;
                }
                tem=tem+to_string(value)+a[t];
                t++;
            }
            a=tem;
            tem="";
        }
        return a;
    }
};

2.9  編寫一個函式來查詢字串陣列中的最長公共字首。

如果不存在公共字首,返回空字串 ""

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs)
    {
        if(strs.empty()) return string();
        int min=999;
        int n=strs.size();
        for(int i=0;i<n;i++)
        {
            if(strs[i].size()>min) min=strs[i].size();
        }
        string common;
        bool is_break=false;
        for(int j=0;j<min;j++)
        {
            char tem=strs[0][j];
            for(int i=0;i<n;i++)
            {
                if(tem==strs[i][j])
                {
                    if(i==n-1) common+=tem;
                }
                else
                {
                    is_break=true;
                    break;
                }
            }
            if(is_break)break;
        }
        return common;                                                      
    }
};