Leetcode 编程中好用的一些C++用法

 1.取vector的子集

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

这里是指,取vc.begin()+1到末尾的所有元素,从而形成一个新的vector数组。例如:

 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. 最大二叉树

  给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  二叉树的根是数组中的最大元素。
  左子树是通过数组中最大值左边部分构造出的最大二叉树。
  右子树是通过数组中最大值右边部分构造出的最大二叉树。
  通过给定的数组构建最大二叉树,并且输出这个树的根节点。

代码如下:

 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 };

 下边是可执行代码:

 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 }
View Code

执行结果如下:

    由上图可知,对于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];

posted @ 2019-12-26 13:47  _小学生  阅读(1207)  评论(0编辑  收藏  举报