【Leetcode】題目集:31-40

Bonstoppo發表於2018-12-27

31.下一個排列中等

學會了reverse函式。這個函式是反轉指定的vector容器裡面的資料。給出下標就可使用,無返回值,存在algorithm下。其次還學到了,一定要在腦中先形成一個演算法框架,然後再去動筆寫,如果有必要的話,可以將程式碼思路寫在紙上。

這個題目的思路是首先確定是不是從大到小的排列出來的。如果是的話,直接反轉,我這裡用的是flag;其次再說一下一般的情況,首先要確定的是該序列是要求遞增的。1.首先是從後往前找。找到第一個後一個數字比前一個數字大的(遞增)那個位置,然後標記這個位置。2.再次從後往前找,找到到該位置之前,有第一個數字比他大,則交換。然後再交換位置之後,對第一次標記位置之後的所有數字進行再次倒序交換。最後交換的意義在於,如果第一輪都沒有發現這樣的資料的話,那麼後面的必定都是按照從大到小的排列的,那麼直接對其完全反轉就行了。全排列啊喂!

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        bool flag = 0;
        int k1 = nums.size() - 2 , j = nums.size() - 1;
        //從後往前找,找到第一個後一個數字比前一個數字大的那個位置//
        for(int i = nums.size() - 2 ; i >= 0 ; i --){
            if(nums[i] < nums[i + 1]){
                flag = 1;
                k1 = i;
                break;
            }
        }
        
        //從後往前找,找到在到這個數字之前的那個位置有沒有比它的大的,如果有就交換//
        if(k1 >= 0){
          for(int j = nums.size() - 1 ; j > k1 ; j --)
            if(nums[j] > nums[k1]){  
                swap(nums[j] , nums[k1]);
                break;
            }
        }
        //交換剩餘的東西//
        if(flag == 1)
            reverse(nums.begin() + k1 + 1, nums.end());
        else{
            reverse(nums.begin() , nums.end());   
        }
    }
};

 

32.最長有效括號困難

學會了字串不屬於基本型別,對於單個的比較就是利用單引號字串。由於字串不屬於基本型別,如果要是入棧的話就直接入棧它的地址下標。還學著利用了動態規劃,但是用的還是不是很好,其實也沒有弄清楚這個到底是什麼意思。還需要整理思路。

首先先考慮特殊情況,這個地方不做特殊說明。以後也會直接忽略,直接說一般的情況。如果遇到一個‘(’,則直接將他彈入到棧中;遇到‘)’的時候,先判斷是否為空,如果為空的話,說明就是“)()”這種情況。第一個永遠匹配不到,那麼就將這個開始的指標向後移動一位。如果不為空的時候,說明裡面有'('這個,將它彈出,隨後考慮這個狀態下的匹配的個數。首先判斷:此時是否為空?如果是的話,說明裡面沒有'('了,那麼也就沒有巢狀的問題,那麼就是直接看目前的‘)’是第幾個,然後和目前的res的數值比較。這個狀態的例子就是“()()()()()”這種。但是如果此時不為空,說明裡面還有巢狀,就是“(()”這種情況,i - v.top()就是目前的長度。注意的是,我們要求的是長度,不是個數。

class Solution {
public:
    int longestValidParentheses(string s) {
       //魯棒性:0和1 都構不成子串//
        if(s.size() == 0 || s.size() == 1){
           return 0;
        }
        
       //一般情況:用棧//
        stack<int> v;
        int start = 0 , res = 0;
        for(int i = 0 ; i < s.size() ; i ++){
            if(s[i] == '('){
                v.push(i);
            }
            else if(s[i] == ')'){
                if(v.empty() == 1){
                    start = i + 1;
                }
                else{
                    v.pop();
                    res = v.empty() == 1 ? max(res , i - start + 1) : max(res , i - v.top());
                }
            }
        }
        return res;
    }
};

 

32.搜尋旋轉排序陣列中等

學到了:溫習二分法。

這個地方不能用

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int start = 0 , end = nums.size() - 1 ;
        while(start <= end){
            if(nums[start] == target){
                return start;
            }
            if(nums[end] == target){
                return end;
            }
            int middle = (start + end) / 2;
            if(nums[middle] == target){
                return middle;
            }
            if(nums[start] > nums[middle]){
                if(nums[middle] < target && nums[start] > target){
                    start = middle + 1;
                }
                else{
                    end = middle - 1;
                }
            }
            else{
                if(nums[middle] > target && nums[start] < target){
                    end = middle - 1;
                }else{
                    start = middle + 1;
                }
            }
        }
        return -1;
    }  
};

 

34.在排序陣列中查詢元素的第一個和最後一個位置中等

複習二分法。

這個地方就是利用二分法先找到其中某一個元素的位置,然後在這個位置上面左右移動指標找到位置。

class Solution {
public:    
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> v;
        int start = 0 , end = nums.size() - 1;
        int k1 = -1 , k2 = -1; 
        while(start <= end){
            int middle = (start + end) / 2;
            if(nums[middle] == target){
                int i = middle , j = middle;
                while(i >= 0 && nums[i] == target){
                    i --;
                    k1 = i + 1;//因為每次跳出來之後數字就已經發生變化了,已經減小了一位了,需要補回來。//
                }
                while(j < nums.size()&& nums[j] == target){
                    j ++;
                    k2 = j - 1;
                }
                v.push_back(k1);
                v.push_back(k2);
                return v;
            }
            if(nums[middle] < target){
                start = middle + 1;
            }
            if(nums[middle] > target){
                end = middle - 1;
            }
        }
        v.push_back(k1);
        v.push_back(k2);
        return v;
    }
};

 

35.搜尋插入位置簡單

遇到的下標比這個數值大,則選擇這個。最後需要考慮的就是那超過陣列最大的那個。

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

 

相關文章