アルゴリズムのメモ_12.16-12.22

今週は、ブラシを続けるの配列クラスのアルゴリズムの問題を-

11.パリンドローム配列を確認してください

文字列を考えると、それは回文文字列であることを確認し、唯一のアルファベットと数字を検討し、大文字小文字を無視することができます。

示例 1:

输入: "A man, a plan, a canal: Panama"
输出: true

説明:この問題では、我々は有効な回文配列として空の文字列を定義します。

ソリューション

  • ダブルポインタ方式
    スキップされた文字の文字/数字が同じで比較した各ペアの要件を満たして遭遇したミドルスキャンに正面から二つのポインタを使用していません
class Solution {
public:
    bool isPalindrome(string s) {
        int i1 = 0;
        int i2 = s.size()-1;

        while(i1 < i2){
            while(!is_char(s[i1]) && (i1 < i2)) ++i1;
            while(!is_char(s[i2]) && (i1 < i2)) --i2;
            if(!equal_character(s[i1], s[i2])) return false;
            ++i1;
            --i2;
        }

        return true;    
    }

    bool is_char(char c){
        if( ((c >= '0') && (c <= '9')) ||
            ((c >= 'a') && (c <='z')) || 
            ((c >= 'A') && (c <= 'Z'))) return true;
        else return false;
    }

    bool equal_character(char c1, char c2){
        int char_dis = 32;
        if((c1 >= 'a') && (c1 <= 'z')){
            c1 -= char_dis;
        }

        if((c2 >= 'a') && (c2 <= 'z')){
            c2 -= char_dis;
        }
        if(c1 == c2) return true;
        else return false;
    }
};

複雑性分析

時間の複雑さ:O(n)は、一度だけスキャンします。

宇宙複雑:O(1)は、追加のスペース。


12.二つの数字II - 入力規則的な配列

所与の順序付けられた配列は、それらの合計が目標数の和に等しくなるように2つの数値を見つけるために応じて昇順にソートされています。

関数は、インデックス1のINDEX2未満でなければならない2つのインデックス値からindex1のINDEX2を返す必要があります。

説明:

インデックス値(インデックス1、INDEX2とは)スタートカウントから返されます。

あなたは、各入力のみ唯一の答えに対応すると仮定することができますが、同じ要素を再利用することはできません。

示例 1:

输入: numbers = [2, 7, 11, 15], target = 9

输出: [1,2]

解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

ソリューション

  • 指ビス(p-ポインタ衝突)
class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int i = 0, j = numbers.size()-1;   //对撞指针法
        //利用数组有序的性质,通过头和尾两个指针逐渐向中间靠拢(头尾两数之和小于目标时增加头指针,反之减少尾指针)来筛除不符合条件的组合,从而得到符合条件的组合
        while(i<j){
            if((numbers[i] + numbers[j]) == target){
                return {i+1, j+1};
            }
            if((numbers[i] + numbers[j]) < target){
                ++i;
            }
            
            if((numbers[i] + numbers[j]) > target){
                --j;
            }
        }
        return {0, 0};
    }
};

複雑性分析

時間計算量:O(n)は、単にアレイ上を走査。

宇宙複雑:O(1)は、追加のスペース。


13.リバース文字列

関数を記述し、その役割は逆に、入力文字列にあります。フォームで指定された文字列の文字を入力文字列[]。

別の配列への追加の領域を割り当てないでください、あなたは、入力配列を変更置き、この問題に余分なスペースO(1)ソリューションを使用する必要があります。

あなたは、アレイ内のすべての文字がASCII表の印刷可能な文字であることを仮定してもよいです。

示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

ソリューション

  • フィンガービス
class Solution {
public:
    void reverseString(vector<char>& s) {
        for(int i = 0; i < s.size()/2; ++i){
            swap(s[i],s[s.size()-1-i]);
        }
    }
};

複雑性分析

宇宙複雑:O(1)は、追加のスペース。
時間計算量:O(n)は、単にアレイ上を走査。


14.リバース母音の文字列

入力として文字列への書き込み機能は、文字列に母音を反転しました。

示例 1:
输入: "hello"
输出: "holle"

ソリューション

  • フィンガービス

スキップ母音文字列アフリカ

class Solution {
public:
    string reverseVowels(string s) {
        int front_ptr = 0;
        int end_ptr = s.size()-1;
        while(front_ptr < end_ptr){
            while(!is_vowel(s[front_ptr]) && (front_ptr < end_ptr)) ++front_ptr;
            while(!is_vowel(s[end_ptr]) && (front_ptr < end_ptr)) --end_ptr;
            swap(s[front_ptr],s[end_ptr]);
            ++front_ptr;
            --end_ptr;
        }
        return s;    
    }
    bool is_vowel(char ch){
        if((ch == 'a') || (ch == 'e') 
        || (ch == 'i') || (ch == 'o') 
        || (ch == 'u') || (ch == 'A') || (ch == 'E') 
        || (ch == 'I') || (ch == 'O') 
        || (ch == 'U')) {return true;}
        else return false;
    }
    };


複雑性分析

宇宙複雑:O(1)は、追加のスペース。
時間の複雑さ:O(n)は、単純に再び文字列をスキャンします。


15.いっぱいの水のコンテナ

所与のn非負整数A1、A2、...、ポイント(iは、AI)各座標の数を表します。垂直座標内の動画n行、私は2つのエンドポイントは、(i、AI)及び(I、0)は垂直線です。x軸の構成は、水を収容できるように一緒に容器を有する2本のラインを見つけます。

注:あなたは、コンテナを傾けることができない、とnの値が2以上です。

図の縦線は、入力配列[1,8,6,2,5,4,8,3,7]です。 この場合、水を保持することができる最大のコンテナ49の(青色で示します)。
図の縦線は、入力配列[1,8,6,2,5,4,8,3,7]です。この場合、水を保持することができる最大のコンテナ49の(青色で示します)。

示例 1:
输入: [1,8,6,2,5,4,8,3,7] 
输出: 49

ソリューション

  • 指ビス(p-ポインタ衝突)

ショートプレートを用いた容器の容量によって決定され、各プレートは、中間ショートに移動させます

class Solution {
public:
    int maxArea(vector<int>& height) {
        int front_ptr = 0, end_ptr = height.size() - 1;
        int max_water = 0;
        if(height[front_ptr] > height[end_ptr]){
            max_water = height[end_ptr] * (end_ptr - front_ptr);
        }
        else max_water = height[front_ptr] * (end_ptr - front_ptr); 

        while(front_ptr < end_ptr){//对撞指针法,利用容器容量由短板决定,每次将短板向中间移动
            if(height[front_ptr] > height[end_ptr]){
                while(height[front_ptr] > height[end_ptr] && (front_ptr < end_ptr)){
                    if(height[end_ptr] * (end_ptr-front_ptr) > max_water){
                        max_water = height[end_ptr] * (end_ptr-front_ptr);
                    }
                    --end_ptr;
                }
            }
            else{
                while(height[front_ptr] <= height[end_ptr] && (front_ptr < end_ptr)){
                    if(height[front_ptr] * (end_ptr - front_ptr) > max_water){
                        max_water = height[front_ptr] * (end_ptr - front_ptr);
                    }
                    ++front_ptr;
                }
            }      
       }
    return max_water;
    }
};

複雑性分析

宇宙複雑:O(1)は、追加のスペース。

時間の複雑さ:O(n)は、単純に再び文字列をスキャンします。


16.最小のサブ配列の長さ

正の整数nは正の整数であり、Sの配列を指定し、アレイを満たす最小の長さと≥複数の連続するサブ配列を見つけます。連続サブ配列修飾が存在しない場合は、0が返されます。

示例 1:
输入: s = 7, nums = [2,3,1,2,4,3] 
输出: 2

説明:サブアレイ[4,3]は、この条件下での連続部分配列の最小の長さです。

ソリューション

  • 指ビス(スライディングウィンドウ)、
    ウィンドウ法をスライドの二重インデクシング方法を使用して、右スライディングウィンドウアレイがSより大きく、左側のウィンドウである(ウィンドウが減少する)、右スライディングウィンドウアレイが少ないSより、右窓(増加したウィンドウ)
class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        if(nums.size() == 0) return 0;
        int first_ptr = 0, second_ptr = 0;//利用双索引法中的滑动窗口法,窗口数组和大于s时向右滑动左窗口(减小窗口),窗口数组和小于s时向右滑动右窗口(增大窗口)
        int sum_int=nums[first_ptr];
        int min_len = 0; 

        while(second_ptr < nums.size() || (sum_int >= s)){
            if(sum_int < s && (second_ptr < nums.size())){
                if(second_ptr < nums.size() - 1){
                    ++second_ptr;
                    sum_int += nums[second_ptr];
                }
                else ++second_ptr;          
            }
            if(sum_int >= s && (first_ptr < nums.size())){
                if((min_len == 0) || ((second_ptr-first_ptr+1) < min_len)){
                    min_len = second_ptr - first_ptr +1;
                }
                sum_int -= nums[first_ptr];
                ++first_ptr;               
            }
        }
        return min_len;      
    }
};

複雑性分析

宇宙複雑:O(1)は、追加のスペース。

時間の複雑さ:O(n)は、単純に再び文字列をスキャンします。


17. A非反復文字最長ストリング

文字列を考えると、あなたは、繰り返し文字の最長の文字列のサブ長さを含んでいないかを調べます。

示例 1:
输入: "abcabcbb" 
输出: 3 

説明:繰り返しのない文字の最長のサブストリングがあるので
、その長さは3であるので、「ABC」は、

ソリューション

  • 指ビス(スライディングウィンドウ)

ウィンドウ法をスライディングのダブルインデックスメソッドを使用してスライドを、左のウィンドウスライディングウィンドウが表示されます(縮小画面)が右に文字が繰り返され、右(増加のウィンドウ)に文字を繰り返すことなく、ウィンドウ右側のウィンドウ

私たちは、文字セットが適切な時期に比較的小さい知っているとき、私たちは直接アクセステーブルとして整数の配列で地図を置き換えることができます。

:一般的に使用されるテーブルは、次の通りである
' - ' Z 'INT文字'A' -'z 'または' Aのための[26である]
INT [128] ASCIIコードのために
INT [256]拡張ASCIIコードの

class Solution {
 public:
  int lengthOfLongestSubstring(string s) {
    int char_freq[256] = {0};//利用256长度的数组储存字串内出现过的字符信息
    int first = 0, second = 0;//滑动窗口法s[first,second]内为最长子串
    char_freq[s[second]] = 1;
    int sub_length = 1;
    char new_char;
 
    if(s.size() == 0) return 0;
    while (first < s.size()) {
      while (second < (s.size() - 1)) {
        new_char = s[++second];
        if (char_freq[new_char] == 1)
          break;
        else {
          char_freq[new_char] = 1;
          sub_length = max(sub_length, second - first + 1);
        }
      }
      while (s[first] != new_char) {
        char_freq[s[first++]] = 0;
      }
      ++first;
    }
    return sub_length;
  }
};

複雑性分析

宇宙複雑:O(1)は、追加のスペース。

時間の複雑さ:O(n)は、単純に再び文字列をスキャンします。


公開された28元の記事 ウォンの賞賛4 ビュー1151

おすすめ

転載: blog.csdn.net/tuziaaa/article/details/103557266