天天看點

Leetcode 程式設計中好用的一些C++用法

 1.取vector的子集

vector<int>(vc.begin() + 1, vc.end())      

這裡是指,取vc.begin()+1到末尾的所有元素,進而形成一個新的vector數組。例如:

Leetcode 程式設計中好用的一些C++用法
Leetcode 程式設計中好用的一些C++用法
1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     vector<int> vc;
 9     vc.resize(10,0);
10     for (int i = 0; i < 10; i++) {
11         vc[i] = i;
12     }
13     for (int j = 0; j < (vector<int>(vc.begin() + 1, vc.end())).size(); j++)
14         cout << (vector<int>(vc.begin() + 1, vc.end()))[j] << endl;
15     return 0;
16 }      

View Code

此種用法,在分治或遞歸思想中用的較多,如下一道題:

  654. 最大二叉樹

  給定一個不含重複元素的整數數組。一個以此數組建構的最大二叉樹定義如下:

  二叉樹的根是數組中的最大元素。

  左子樹是通過數組中最大值左邊部分構造出的最大二叉樹。

  右子樹是通過數組中最大值右邊部分構造出的最大二叉樹。

  通過給定的數組建構最大二叉樹,并且輸出這個樹的根節點。

Leetcode 程式設計中好用的一些C++用法

代碼如下:

1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 private:
12     TreeNode* helper(const vector<int>& nums)
13     {
14         auto it = max_element(nums.begin(), nums.end());
15         if (it == nums.end())   return nullptr;
16         TreeNode* root = new TreeNode(*it);
17         root->left = helper(vector<int>(nums.begin(), it));
18         root->right = helper(vector<int>(it + 1, nums.end()));
19 
20         return root;
21     }
22 public:
23     TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
24         TreeNode* root = helper(nums);
25 
26         return root;    
27     }
28 };      

思想:

  每次找到vector中的最大值,這裡用的是max_element()函數,然後遞歸建構前半個數組,即

  vector<int>(nums.begin(), it) 和 後半個數組,即      
  vector<int>(it + 1, nums.end())      
2.STL中的max_element函數
      

  函數功能:指向序列之中數組最大元素,包含在algorithm庫中。

       函數傳回疊代器,時間複雜度O(n)。

  函數原型如下所示:

  

  213. 打家劫舍 II

 你是一個專業的小偷,計劃偷竊沿街的房屋,每間房内都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味着第一個房屋和最後一個房屋是緊挨着的。同時,相鄰的房屋裝有互相連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。 

給定一個代表每個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。

示例 1:

輸入: [2,3,2]

輸出: 3

解釋: 你不能先偷竊 1 号房屋(金額 = 2),然後偷竊 3 号房屋(金額 = 2), 因為他們是相鄰的。

分析:

  環狀結構可以了解為傳回前(n-1)和後(n-1)中的最大金額中的最大值!

1 class Solution {
 2 public:
 3     int rob(vector<int>& nums) {
 4         if(nums.size()==0)
 5             return 0;
 6         if(nums.size()==1)
 7             return nums[0];
 8         return max(func((vector<int> (nums.begin(),nums.end()-1))),func((vector<int> (nums.begin()+1,nums.end()))));
 9     }
10 
11     int func(vector<int> nums){
12         //傳回nums中的最高金額
13         if(nums.size()==1)
14             return nums[0];
15         if(nums.size()==2)
16             return max(nums[0],nums[1]);
17         vector<int> vc;
18         vc.resize(nums.size(),0);
19         vc[0]=nums[0];
20         vc[1]=max(nums[0],nums[1]);
21         for(int i=2;i<nums.size();i++)
22         {
23             vc[i]=max(vc[i-1],nums[i]+vc[i-2]);
24         }
25         return vc[nums.size()-1];
26     }
27 };      

此處,也用到了vector的子數組,将vector子數組作為參數。

return max(func((vector<int> (nums.begin(),nums.end()-1))),func((vector<int> (nums.begin()+1,nums.end()))));      
3.string和char之間的轉換
      

  1002. 查找常用字元

  分析:

  首先,建立一個二維數組,26列記錄每個單詞中a~z的個數,a~z的ASCII碼值為97~122,是以下标為A[i][j]-97;

  然後,統計每一列的最小值,初始值為0,如果某一個字母,有的單詞中不存在,則該列中的最小值應該為0;

  最後,根據最小值min,向結果集中填充min個字母,假定列為j,則填充的字母為 char(j+97)。

1 class Solution {
 2 public:
 3     vector<string> commonChars(vector<string>& A) {
 4         vector<string> res;
 5         //初始化二維數組 A.size() * 26
 6         vector<vector<int>> vc;
 7         vector<int> level;
 8         level.resize(26,0);
 9         vc.resize(A.size(),level);
10 
11         //填表
12         for(int i=0;i<A.size();i++)
13         {
14             for(int j=0;j<A[i].length();j++)
15             {
16                 vc[i][A[i][j]-97]++;
17             }
18         }
19 
20         //統計最小值
21         int min;
22         string temp="";
23         for(int j=0;j<26;j++){
24             min=100; //初始化最小值,每個最小值不會超過100
25             for(int i=0;i<A.size();i++)
26             {
27                 //每一列的最小值
28                 if(vc[i][j]<min)
29                     min=vc[i][j];
30             }
31             //統計出最小值,在結果集中填充對應的字母個數
32             while(min--){
33                 temp.clear();
34                 temp.push_back(char(j+97));
35                 res.push_back(temp);
36             }
37         }
38         return res;
39     }
40 };      

 下邊是可執行代碼:

Leetcode 程式設計中好用的一些C++用法
Leetcode 程式設計中好用的一些C++用法
1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 
 5 using namespace std;
 6 vector<string> commonChars(vector<string>& A) {
 7     vector<string> res;
 8     //初始化二維數組 A.size() * 26
 9     vector<vector<int>> vc;
10     vector<int> level;
11     level.resize(26, 0);
12     vc.resize(A.size(), level);
13 
14     //填表
15     for (int i = 0; i < A.size(); i++)
16     {
17         for (int j = 0; j < A[i].length(); j++)
18         {
19             vc[i][A[i][j] - 97]++;
20         }
21     }
22     cout << "The array is as follow:" << endl;
23     for (int i = 0; i < 26; i++)
24     {
25         cout << char(i + 97) << " ";
26     }
27     cout << endl;
28     for (int i = 0; i < A.size(); i++)
29     {
30         for (int j = 0; j < 26; j++)
31         {
32             cout << vc[i][j]<<" ";
33         }
34         cout << endl;
35     }
36 
37     //統計最小值
38     int min;
39     string temp = "";
40     for (int j = 0; j < 26; j++) {
41         min = 100; //初始化最小值,每個最小值不會超過100
42         for (int i = 0; i < A.size(); i++)
43         {
44             //每一列的最小值
45             if (vc[i][j] < min)
46                 min = vc[i][j];
47         }
48         //統計出最小值,在結果集中填充對應的字母個數
49         while (min--) {
50             temp.clear();
51             temp.push_back(char(j + 97));
52             res.push_back(temp);
53         }
54     }
55     cout << "res is as follows" << endl;
56     for (int i = 0; i < res.size(); i++)
57     {
58         cout << "\"" <<res[i] <<"\" ";
59     }
60     cout << endl;
61     return res;
62 }
63 
64 int main()
65 {
66     vector<string> aa;
67     int n;
68     cout << "Please input the number of words:" << endl;
69     cin >> n;
70     aa.resize(n);
71     cout << "Please input the each word:" << endl;
72     for (int i = 0; i < n; i++)
73     {
74         cin >> aa[i];
75     }
76     commonChars(aa);
77     return 0;
78 }      

執行結果如下:

    由上圖可知,對于e來說,每個單詞中都包含一次,是以,e列的最小值為1,向結果集中填充1個“e”,對于o列,最小值為0,說明至少有一個單詞中,不包含該字母,是以,該字母不會放入到結果集。

  這裡須注意,放入結果集的值string類型,而非char類型,直接放進去肯定是對的,但是char如何轉string?

1 //統計出最小值,在結果集中填充對應的字母個數
2         while (min--) {
3             temp.clear();
4             temp.push_back(char(j + 97));
5             res.push_back(temp);
6         }      

  這部分代碼中包含轉換過程,将temp聲明為了string類型,相當于一個vector<char>類型,是以可以直接将char類型的字母push_back進去,然後整體看作string類型,放入res中。

在CSDN上看的三種方式:

//1、構造函數裡有個string(size_t,char)
char x = 'a';
string s(1,x);
//2、string初始化沒char,但是push_back可以
string s;
s.push_back(x);
//3、string可以由char*初始化
char xx[2] = {x,0};
string s(xx)      

 4.string和char之間的轉換

  118. 楊輝三角

 分析:

  res[i][0]=res[i][i-1]=1;

  res[i][j]=res[i-1][j-1]+res[i-1][j];

1 class Solution {
 2 public:
 3     vector<vector<int>> generate(int numRows) {
 4         vector<vector<int>> res;
 5         vector<int> level;
 6         if(numRows==1)
 7         {
 8             level.push_back(1);
 9             res.push_back(level);
10             return res;
11         }
12         for(int i=1;i<=numRows;i++)
13         {
14             level.resize(i);
15             for(int j=0;j<i;j++)
16             {
17                 if(j==0 || j==i-1)
18                     level[j]=1;
19                 else{
20                     level[j]=res.back()[j-1]+res.back()[j];
21                 }
22             }
23             res.push_back(level);
24         }
25         return res;
26     }
27 };      

注意點: 

  對于vector,最後一項我們可以用res[res.size()-1]來擷取,同樣,res.back()也是最後一項。

  如上述代碼所示,res為二維數組,所有,其最後一項傳回值為一個一維數組,可以直接通過索引進行通路,level[j]=res.back()[j-1]+res.back()[j];