leecode刷水題

大佬估計對水題沒什麼興趣,所以就輪到我刷刷水題,提高一點自信心了:D

1021.有效括號字符串爲空 ("")、"(" + A + “)” 或 A + B,其中 A 和 B 都是有效的括號字符串,+ 代表字符串的連接。例如,"","()","(())()" 和 “(()(()))” 都是有效的括號字符串。

如果有效字符串 S 非空,且不存在將其拆分爲 S = A+B 的方法,我們稱其爲原語(primitive),其中 A 和 B 都是非空有效括號字符串。

給出一個非空有效字符串 S,考慮將其進行原語化分解,使得:S = P_1 + P_2 + … + P_k,其中 P_i 是有效括號字符串原語。

對 S 進行原語化分解,刪除分解中每個原語字符串的最外層括號,返回 S 。

思路:很像是以前的一道匹配括號是否合格的題,用stack,當爲’(‘壓入,當爲’)'彈出,增加一個輔助sring,當不爲外層括號時,將字符加入

class Solution {
public:
    string removeOuterParentheses(string S) {
        string::iterator it = S.begin();
        while(it != S.end())//注意因爲有pop所以不能使用it++ != S.end()否則會產生錯誤
        {
             
            if(*it == ')')
            {
                opp.pop();
                
            }
            it++;
            if(opp.empty()!=1)
            {
                res+=*it;
            }
            if(*it == '(')
                opp.push(*it);
           
        }
        return res;
        
    }
    private:
    stack<char> opp;
    string res;
};
  1. 二叉搜索樹的範圍和
    給定二叉搜索樹的根結點 root,返回 L 和 R(含)之間的所有結點的值的和。
    二叉搜索樹保證具有唯一的值。
    思路:我覺得出題人的語文需要重新學習,這道題的意思是遍歷該二叉樹並且返回L和R間的節點的值的和。
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int rangeSumBST(TreeNode* root, int L, int R) {
        if(root != nullptr)
        {
            if(root->val>=L&& root->val <= R)
                sum += root->val;
        }
        if(root->left != nullptr)
            rangeSumBST(root->left, L, R);
        if(root->right != nullptr)
            rangeSumBST(root->right, L, R);
            return sum;
    }
    private:
    int sum = 0;
};
  1. 二叉樹的層次遍歷 II
    給定一個二叉樹,返回其節點值自底向上的層次遍歷。 (即按從葉子節點所在層到根節點所在的層,逐層從左向右遍歷)

思路:用迭代的方式,設置一個輔助隊列,先把根節點傳進來,再把隊列的size作爲循環條件,每次循環就要判斷節點的左右是否爲空,不爲空就傳入隊列中,循環size次,每將該隊列的值傳入到vector中,結束當前循環後,將vector傳入到vector<vector>,並且清空vector,直到queue爲空,將vector<vector>逆轉,並且返回。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        vector<vector<int>> sum;
        vector<int> nod;
        queue<TreeNode*> mid;
        if(root == nullptr)
            return sum;
        mid.push(root);
        while(!mid.empty())
        {
            int size = mid.size();
            for(int i=0;i<size;i++)
            {
                nod.push_back(mid.front()->val);
                TreeNode* front = mid.front();
                mid.pop();
                if(front->left)
                {
                    mid.push(front->left);
                }
                if(front->right)
                {
                    mid.push(front->right);
                }
                
            }
            sum.push_back(nod);
                nod.clear();
            
            
        }
        reverse(sum.begin(),sum.end());
            return sum;
    }
};

給定兩個字符串 s 和 t,它們只包含小寫字母。

字符串 t 由字符串 s 隨機重排,然後在隨機位置添加一個字母。

請找出在 t 中被添加的字母。

思路:一般的思路是用數組來解,每一個字母可以作爲數組的下標,出現一次++,最後統計哪個下標增加,返回就行了。但是,看了網上的“奇技淫巧”,大開眼界,下面是我覺的腦回路驚奇的代碼。

class Solution {
public:
    char findTheDifference(string s, string t) {
        int count = 0;
        for(auto& i: t)
        {
            count +=i;
        }
        for(auto& i: s)
        {
            count -=i;
        }
        
        return count;
    }
};
  1. 位1的個數
    輸入是一個無符號整數,返回其二進制表達式中數字位數爲 ‘1’ 的個數(也被稱爲漢明重量)。

思路:對傳入的值進行位操作,只要不是剛學編程的,估計都能做對。

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int i=0;
        
        while(n!=0)
        {
            if(n&1)
             i++;
           n = n>>1;
        }
        return i;
    }
};
  1. Pow(x, n)
    實現 pow(x, n) ,即計算 x 的 n 次冪函數。

看起來很簡單的題,但是暗藏殺機,因爲測試案例裏有,類似-1.00000
-2147483648這樣的輸入參數,想要計算不超時,只能考慮複雜度位logn的算法。
使用折半計算,每次把n縮小一半,這樣n最終會縮小到0,任何數的0次方都爲1,這時候我們再往回乘,如果此時n是偶數,直接把上次遞歸得到的值算個平方返回即可,如果是奇數,則還需要乘上個x的值。還有一點需要引起我們的注意的是n有可能爲負數,對於n是負數的情況,我們可以先用其絕對值計算出一個結果再取其倒數即可。我們讓i初始化爲n,然後看i是否是2的倍數,是的話x乘以自己,否則res乘以x,i每次循環縮小一半,直到爲0停止循環。最後看n的正負,如果爲負,返回其倒數。

class Solution {
    public double myPow(double x, int n) {
        double res = 1.0;
        for(int i = n; i != 0; i /= 2){
            if(i % 2 != 0){
                res *= x;
            }
            x *= x;
        }
        return  n < 0 ? 1 / res : res;
    }
} 

給定一組不含重複元素的整數數組 nums,返回該數組所有可能的子集(冪集)。

說明:解集不能包含重複的子集。

輸入: nums = [1,2,3]
輸出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

思路:可以認爲每個元素都有兩種選擇,加入子集或者不加入,用狀態符0和1表示,有size個元素,就有size^2種情況,就遍歷1到size 與1到size ^2進行&運算,如果爲真將該元素加入子集,否則跳過。

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> end;
        vector<int> temp;//空
        int k = 1;
        int size = nums.size();
        int hash = (1<<size);
        
       
        
        while(k<=hash)
        {
            temp.clear();
            for(int i=0;i<size;i++)
            {
                int m = (1<<i);
                if(k& m)
                {
                    temp.push_back(nums[i]);
                    
                }
            }
            end.push_back(temp);
            k++;
        }
        return end;
        
    }
};
  1. 翻轉二叉樹
    翻轉一棵二叉樹。

示例:
輸入:
4
/
2 7
/ \ /
1 3 6 9
輸出:
4
/
7 2
/ \ /
9 6 3 1

思路:前中後序遍歷,選一個,交換左節點和右節點指針。

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr)
            return root; 
        
        if(root->left)
        invertTree(root->left);
         if(root->right)
        invertTree(root->right);
        
        
        
            TreeNode* m = root->left;
            root->left = root->right;
            root->right = m;
            
        
      
        return root;
    }
};
  1. 除自身以外數組的乘積
    給定長度爲 n 的整數數組 nums,其中 n > 1,返回輸出數組 output ,其中 output[i] 等於 nums 中除 nums[i] 之外其餘各元素的乘積。

可以用左右累乘法來解決

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> num2(nums.size(),1);
        int left = 1;
        int right = 1;
        int n = nums.size();
        for(int i=0;i<nums.size();i++)
        {
            num2[i] *= left;
            left    *= nums[i];
            num2[n-i-1] *= right;
            right *= nums[n-i-1];

        }
        
        return num2;
        
    }
};

有序數組中的單一元素
給定一個只包含整數的有序數組,每個元素都會出現兩次,唯有一個數只會出現一次,找出這個數。

挺有趣的題目,注意有序數組的條件,複雜度爲n的解法是,每兩個單位爲一組,從前往後判斷是否相等,如果相等跳過,如果不相等,返回第一個不相等的元素。
複雜度爲logn的解法利用了快排的思想,判斷中間的元素和左邊的是否相同,如果相同,判斷左邊除中點的元素是否爲偶數,如果爲偶數說明,答案在左邊,更新左右邊界值,同理如果不相同,再判斷是否和右邊的元素相同,步驟和上面一樣,如果左右都不相同,直接返回中點值。

class Solution {
public:
    int singleNonDuplicate(vector<int>& num) {
      
       int left = 0;
       int right = num.size()-1;
      
       while(left < right)
       {
           int mid = (left +right)/2;
           if(num[mid] == num[mid-1])
           {
               if((mid - left)%2 == 0)//判斷左邊的元素個數是否爲偶數
               {
                   right =mid - 2 ;
               }
               else
               {
                    left = mid+1;
               }
           }
           else if(num[mid] == num[mid+1])
           {
               if((right - mid)%2 == 0)
               {
                   left = mid+2;
               }
               else
               {
                   right = mid-1;
               }
           }
           else
           {
               return num[mid];
           }
           
       }
        return num[left];
    }
        
};
  1. Nim 遊戲
    你和你的朋友,兩個人一起玩 Nim 遊戲:桌子上有一堆石頭,每次你們輪流拿掉 1 - 3 塊石頭。 拿掉最後一塊石頭的人就是獲勝者。你作爲先手。

你們是聰明人,每一步都是最優解。 編寫一個函數,來判斷你是否可以在給定石頭數量的情況下贏得遊戲。
在這裏插入圖片描述

你們都是聰明人就我不聰明(。≖ˇェˇ≖。)。
開始的時候想利用動態規劃解決,後來發現只要堆的數量爲4的整數倍,後手必贏,否則先手必贏,叫做巴什博奕,面對4的整數倍的人永遠無法翻身,你拿N根對手就會拿4-N根,保證每回合共減4根,你永遠對面4倍數,直到4. 相反,如果最開始不是4倍數,你可以拿掉剛好剩下4倍數根,讓他永遠對面4倍數。

class Solution {
public:
    bool canWinNim(int n) { 
        return n%4;
    }
};
  1. 買賣股票的最佳時機
    給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。

如果你最多隻允許完成一筆交易(即買入和賣出一支股票),設計一個算法來計算你所能獲取的最大利潤。

注意你不能在買入股票前賣出股票。

遞歸思想,
1.計算截至今天的最低價格
2.計算今天賣出的收益與之前的最大收益進行比較
3.循環, 返回計算結果

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size() <= 1)
            return 0;
        int max = 0;
        int min = prices[0];
        for(int i=0;i<prices.size();i++)
        {
          min = min<prices[i]?min:prices[i];
            max = max>prices[i] - min?max:prices[i] - min;
          
        }
        return max;
        
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章