• 进阶C++__STL__容器vector使用方法【简单易懂】


    目录

    vector容器

    vector构造函数

    vector赋值操作

    vector容量和大小

    vector插入和删除

    vector数据存取

    vector互换容器

    vector预留空间

     reserve()的实现

    vector的增删查改的模拟实现

    经典题目练习 

    1.杨辉三角OJ

    2.删除排序数组中的重复项 OJ

    3. 数组中出现次数超过一半的数字 

    4.只出现一次的数字

    5.电话号码字母组合

    6. 连续子数组的最大和  


    vector容器

    vector构造函数

    • vector v; //采用模板实现类实现,默认构造函数
    • vector(v.begin(), v.end()); //将v[begin(), end())区间中的元素拷贝给本身。
    • vector(n, elem); //构造函数将n个elem拷贝给本身。
    • vector(const vector &vec); //拷贝构造函数。
    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void printVector(vector<int>& v) {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    7. cout << *it << " ";
    8. }
    9. cout << endl;
    10. }
    11. void test01()
    12. {
    13. vector<int> v1; //无参构造 默认构造
    14. for (int i = 0; i < 10; i++)
    15. {
    16. v1.push_back(i);
    17. }
    18. printVector(v1);
    19. //通过区间方式构造
    20. vector<int> v2(v1.begin(), v1.end());
    21. printVector(v2);
    22. // n个元素e方式构造
    23. vector<int> v3(10, 0);
    24. printVector(v3);
    25. //拷贝构造
    26. vector<int> v4(v3);
    27. printVector(v4);
    28. }
    29. int main() {
    30. test01();
    31. system("pause");
    32. return 0;
    33. }

    输出:

    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 0

    vector赋值操作

    • vector& operator=(const vector &vec);//重载等号操作符

    • assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。

    • assign(n, elem); //将n个elem拷贝赋值给本身。

    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void printVector(vector<int>& v) {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    7. cout << *it << " ";
    8. }
    9. cout << endl;
    10. }
    11. //赋值操作
    12. void test01()
    13. {
    14. vector<int> v1; //无参构造
    15. for (int i = 0; i < 10; i++)
    16. {
    17. v1.push_back(i);
    18. }
    19. printVector(v1);
    20. vector<int>v2;
    21. v2 = v1;
    22. printVector(v2);
    23. vector<int>v3;
    24. v3.assign(v1.begin(), v1.end());
    25. printVector(v3);
    26. vector<int>v4;
    27. v4.assign(10, 100);
    28. printVector(v4);
    29. }
    30. int main() {
    31. test01();
    32. system("pause");
    33. return 0;
    34. }

    输出:

    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    100 100 100 100 100 100 100 100 100 100

    vector容量和大小

    • empty(); //判断容器是否为空

    • capacity(); //容器的容量

    • size(); //返回容器中元素的个数

    • resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。

      ​ //如果容器变短,则末尾超出容器长度的元素被删除。

    • resize(int num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。

      ​ //如果容器变短,则末尾超出容器长度的元素被删除

    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void printVector(vector<int>& v) {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    7. cout << *it << " ";
    8. }
    9. cout << endl;
    10. }
    11. void test01()
    12. {
    13. vector<int> v1;
    14. for (int i = 0; i < 10; i++)
    15. {
    16. v1.push_back(i);
    17. }
    18. printVector(v1);
    19. if (v1.empty())
    20. {
    21. cout << "v1为空" << endl;
    22. }
    23. else
    24. {
    25. cout << "v1不为空" << endl;
    26. cout << "v1的容量 = " << v1.capacity() << endl;
    27. cout << "v1的大小 = " << v1.size() << endl;
    28. }
    29. //resize 重新指定大小 ,若指定的更大,默认用0填充新位置,可以利用重载版本替换默认填充
    30. v1.resize(15,10);
    31. printVector(v1);
    32. //resize 重新指定大小 ,若指定的更小,超出部分元素被删除
    33. v1.resize(5);
    34. printVector(v1);
    35. }
    36. int main() {
    37. test01();
    38. system("pause");
    39. return 0;
    40. }

    vector插入和删除

    • push_back(ele); //尾部插入元素ele
    • pop_back(); //删除最后一个元素
    • insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
    • insert(const_iterator pos, int count,ele);//迭代器指向位置pos插入count个元素ele
    • erase(const_iterator pos); //删除迭代器指向的元素
    • erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素
    • clear(); //删除容器中所有元素
    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void printVector(vector<int>& v) {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    7. cout << *it << " ";
    8. }
    9. cout << endl;
    10. }
    11. //插入和删除
    12. void test01()
    13. {
    14. vector<int> v1;
    15. //尾插
    16. v1.push_back(10);
    17. v1.push_back(20);
    18. v1.push_back(30);
    19. v1.push_back(40);
    20. v1.push_back(50);
    21. printVector(v1);
    22. //尾删
    23. v1.pop_back();
    24. printVector(v1);
    25. //插入
    26. v1.insert(v1.begin(), 100);
    27. printVector(v1);
    28. v1.insert(v1.begin(), 2, 1000);
    29. printVector(v1);
    30. //删除
    31. v1.erase(v1.begin());
    32. printVector(v1);
    33. //清空
    34. v1.erase(v1.begin(), v1.end());
    35. v1.clear();
    36. printVector(v1);
    37. }
    38. int main() {
    39. test01();
    40. system("pause");
    41. return 0;
    42. }

    输出:

    10 20 30 40 50
    10 20 30 40
    100 10 20 30 40
    1000 1000 100 10 20 30 40
    1000 100 10 20 30 40

    vector数据存取

    • at(int idx); //返回索引idx所指的数据
    • operator[]; //返回索引idx所指的数据
    • front(); //返回容器中第一个数据元素
    • back(); //返回容器中最后一个数据元素
    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void test01()
    6. {
    7. vector<int>v1;
    8. for (int i = 0; i < 10; i++)
    9. {
    10. v1.push_back(i);
    11. }
    12. for (int i = 0; i < v1.size(); i++)
    13. {
    14. cout << v1[i] << " ";
    15. }
    16. cout << endl;
    17. for (int i = 0; i < v1.size(); i++)
    18. {
    19. cout << v1.at(i) << " ";
    20. }
    21. cout << endl;
    22. cout << "v1的第一个元素为: " << v1.front() << endl;
    23. cout << "v1的最后一个元素为: " << v1.back() << endl;
    24. }
    25. int main() {
    26. test01();
    27. system("pause");
    28. return 0;
    29. }

    输出:

    0 1 2 3 4 5 6 7 8 9
    0 1 2 3 4 5 6 7 8 9
    v1的第一个元素为: 0
    v1的最后一个元素为: 9

    vector互换容器

    • swap(vec); // 将vec与本身的元素互换
    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void printVector(vector<int>& v) {
    6. for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    7. cout << *it << " ";
    8. }
    9. cout << endl;
    10. }
    11. void test01()
    12. {
    13. vector<int>v1;
    14. for (int i = 0; i < 10; i++)
    15. {
    16. v1.push_back(i);
    17. }
    18. printVector(v1);
    19. vector<int>v2;
    20. for (int i = 10; i > 0; i--)
    21. {
    22. v2.push_back(i);
    23. }
    24. printVector(v2);
    25. //互换容器
    26. cout << "互换后" << endl;
    27. v1.swap(v2);
    28. printVector(v1);
    29. printVector(v2);
    30. }
    31. void test02()
    32. {
    33. vector<int> v;
    34. for (int i = 0; i < 100000; i++) {
    35. v.push_back(i);
    36. }
    37. cout << "v的容量为:" << v.capacity() << endl;
    38. cout << "v的大小为:" << v.size() << endl;
    39. v.resize(3);
    40. cout << "v的容量为:" << v.capacity() << endl;
    41. cout << "v的大小为:" << v.size() << endl;
    42. //收缩内存
    43. vector<int>(v).swap(v); //匿名对象
    44. cout << "v的容量为:" << v.capacity() << endl;
    45. cout << "v的大小为:" << v.size() << endl;
    46. }
    47. int main() {
    48. test01();
    49. test02();
    50. system("pause");
    51. return 0;
    52. }

    输出:

    0 1 2 3 4 5 6 7 8 9
    10 9 8 7 6 5 4 3 2 1
    互换后
    10 9 8 7 6 5 4 3 2 1
    0 1 2 3 4 5 6 7 8 9
    v的容量为:131072
    v的大小为:100000
    v的容量为:131072
    v的大小为:3
    v的容量为:3
    v的大小为:3

    总结:swap可以使两个容器互换,可以达到实用的收缩内存效果

    vector预留空间

    reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。

    vector开辟空间原理:

    当空间不够时,会重新开辟一块更大的空间,将原来空间内容拷贝到这个更大的空间,并指向这块空间;

    1. #include
    2. #include
    3. using namespace std;
    4. #include
    5. void test01()
    6. {
    7. vector<int> v;
    8. //预留空间
    9. //v.reserve(100000);
    10. int num = 0;
    11. int* p = NULL;
    12. for (int i = 0; i < 100000; i++) {
    13. v.push_back(i);
    14. if (p != &v[0]) {
    15. p = &v[0];
    16. num++;
    17. }
    18. }
    19. cout << "num:" << num << endl;
    20. }
    21. int main() {
    22. test01();
    23. system("pause");
    24. return 0;
    25. }

    输出:(不同编译器结果不同)

     num:18

    利用开辟空间原理判断指向的地址是否改变,我们发现vector存100000个元素时要改变18次,即重新开辟并拷贝18次;这样非常耗费时间;

    当我们使用reserve直接预留100000空间时,则只需要一次,非常节约时间

     reserve()的实现

    1. /* reserve */
    2. void reserve(size_t new_capacity) {
    3. if (new_capacity > capacity()) { // 检查是否真的需要扩容
    4. if (_finish == _eos) {
    5. size_t sz = size(); // 提前把size算好
    6. T* tmp = new T[new_capacity];
    7. if (_start) {
    8. // memcpy(tmp, _start, sizeof(T) * size()); 有问题!
    9. //自己把原空间的数据拷贝到新空间
    10. for (size_t i = 0; i < sz; i++) {
    11. // 如果T是int,一个一个拷贝没问题
    12. // 如果T是string等自定义问题,一个一个拷贝调用的是T的深拷贝,也不会出问题。
    13. tmp[i] = _start[i];
    14. }
    15. delete[] _start; // 并释放原有的旧空间
    16. }
    17. _start = tmp; // 指向新空间
    18. _finish = tmp + sz; // 现场算size() 会有问题,因为start已经被更新成tmp了
    19. _eos = _start + new_capacity;
    20. }
    21. }
    22. }

    vector迭代器失效问题

    1、缺位删除

    下面这个代码输出的是?

    1. #include
    2. #include
    3. using namespace std;
    4. int main(void)
    5. {
    6. vector<int>array;
    7. array.push_back(100);
    8. array.push_back(300);
    9. array.push_back(300);
    10. array.push_back(300);
    11. array.push_back(300);
    12. array.push_back(500);
    13. vector<int>::iterator itor;
    14. for (itor = array.begin(); itor != array.end(); itor++)
    15. {
    16. if (*itor == 300)
    17. {
    18. itor = array.erase(itor);
    19. }
    20. }
    21. for (itor = array.begin(); itor != array.end(); itor++)
    22. {
    23. cout << *itor << " ";
    24. }
    25. return 0;
    26. }

     100 500 ??错误!!

     for(itor=array.begin();itor!=array.end();itor++)

    {

            if(* itor==300) //向量的数据为300时进行删除

            {

                    //删除之后迭代器进行返回赋值,不会导致迭代器失效,删除当前数据,

                    //后面的数据相当于会向前移动,此时itor还是指向下一个300数据,

                    //但是由于循环回去,for循环末尾itor++会让迭代器指向下一个

                    //数据,因此会错失一次300的比较判断

                    itor=array.erase(itor);

            }

    }

    所以答案为: 100 300 300 500 

    2、删除导致迭代器失效

    结果是?

    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. int ar[] = { 1,2,3,4,0,5,6,7,8,9 };
    7. int n = sizeof(ar) / sizeof(int);
    8. vector<int> v(ar, ar + n);
    9. vector<int>::iterator it = v.begin();
    10. while (it != v.end())
    11. {
    12. if (*it != 0)
    13. cout << *it;
    14. else
    15. {
    16. v.erase(it);
    17. *it=5;
    18. }
    19. it++;
    20. }
    21. return 0;
    22. }

    A.程序运行崩溃

    B.1 2 3 4 5 0 6 7 8 9

    C.1 2 3 4 5 6 7 8 9

    D.1 2 3 4 6 7 8 9


    分析:当迭代器的值为0时,此时会进行删除,删除后如果迭代器不重新赋值,会导致原来的迭代器失效,此时针对一个已经失效的迭代器在进行++,会导致程序崩溃

    故答案为A


    vector的增删查改的模拟实现

    函数接口:

    1. namespace bit
    2. {
    3. template<class T>
    4. class vector
    5. {
    6. public:
    7. // Vector的迭代器是一个原生指针
    8. typedef T* iterator;
    9. typedef const T* const_iterator;
    10. iterator begin()
    11. iterator end()
    12. const_iterator cbegin()
    13. const_iterator cend() const
    14. // construct and destroy
    15. vector()
    16. vector(int n, const T& value = T())
    17. template<class InputIterator>
    18. vector(InputIterator first, InputIterator last)
    19. vector(const vector& v)
    20. vector& operator= (vector v);
    21. ~vector();
    22. // capacity
    23. size_t size() const
    24. size_t capacity() const
    25. void reserve(size_t n)
    26. void resize(size_t n, const T& value = T())
    27. ///access///
    28. T& operator[](size_t pos)
    29. const T& operator[](size_t pos)const
    30. ///modify/
    31. void push_back(const T& x)
    32. void pop_back()
    33. void swap(vector& v)
    34. iterator insert(iterator pos, const T& x)
    35. iterator erase(Iterator pos)
    36. private:
    37. iterator _start; // 指向数据块的开始
    38. iterator _finish; // 指向有效数据的尾
    39. iterator _endOfStorage; // 指向存储容量的尾
    40. };
    41. }

     模拟实现

    1. namespace bit
    2. {
    3. template<class T>
    4. class vector
    5. {
    6. public:
    7. // Vector的迭代器是一个原生指针
    8. typedef T* iterator;
    9. typedef const T* const_iterator;
    10. iterator begin()
    11. {
    12. return _start;
    13. }
    14. iterator end()
    15. {
    16. return _finish;
    17. }
    18. const_iterator cbegin()const
    19. {
    20. return _start;
    21. }
    22. const_iterator cend() const
    23. {
    24. return _finish;
    25. }
    26. // construct and destroy
    27. vector(): _start(nullptr), _finish(nullptr), _endOfStorage(nullptr)
    28. {}
    29. vector(int n, const T& value = T())
    30. : _start(nullptr), _finish(nullptr),_endOfStorage(nullptr)
    31. {
    32. reserve(n);
    33. while (n--)
    34. {
    35. push_back(value);
    36. }
    37. }
    38. template<class InputIterator>
    39. vector(InputIterator first, InputIterator last)
    40. {
    41. reserve(last - first);
    42. while (first != last)
    43. {
    44. push_back(*first);
    45. ++first;
    46. }
    47. }
    48. vector(const vector& v)
    49. : _start(nullptr), _finish(nullptr), _endOfStorage(nullptr)
    50. {
    51. reserve(v.capacity());
    52. iterator it = begin();
    53. const_iterator vit = v.cbegin();
    54. while (vit != v.cend())
    55. {
    56. *it++ = *vit++;
    57. }
    58. _finish = _start + v.size();
    59. _endOfStorage = _start + v.capacity();
    60. }
    61. vector& operator= (vector v)
    62. {
    63. swap(v);
    64. return *this;
    65. }
    66. ~vector()
    67. {
    68. delete[] _start;
    69. _start = _finish = _endOfStorage = nullptr;
    70. }
    71. // capacity
    72. size_t size() const
    73. {
    74. return _finish - _start;
    75. }
    76. size_t capacity() const
    77. {
    78. return _endOfStorage - _start;
    79. }
    80. void reserve(size_t n)
    81. {
    82. if (n > capacity())
    83. {
    84. size_t oldSize = size();
    85. T* tmp = new T[n];
    86. if (_start)
    87. {
    88. for (size_t i = 0; i < oldSize; ++i)
    89. tmp[i] = _start[i];
    90. }
    91. _start = tmp;
    92. _finish = _start + size;
    93. _endOfStorage = _start + n;
    94. }
    95. }
    96. void resize(size_t n, const T& value = T())
    97. {
    98. // 1.如果n小于当前的size,则数据个数缩小到n
    99. if (n <= size())
    100. {
    101. _finish = _start + n;
    102. return;
    103. }
    104. // 2.空间不够则增容
    105. if (n > capacity())
    106. reserve(n);
    107. // 3.将size扩大到n
    108. iterator it = _finish;
    109. iterator _finish = _start + n;
    110. while (it != _finish)
    111. {
    112. *it = value;
    113. ++it;
    114. }
    115. }
    116. ///access///
    117. T& operator[](size_t pos)
    118. {
    119. return _start[pos];
    120. }
    121. const T& operator[](size_t pos)const
    122. {
    123. return _start[pos];
    124. }
    125. ///modify/
    126. void push_back(const T& x)
    127. {
    128. insert(end(), x);
    129. }
    130. void pop_back()
    131. {
    132. erase(--end());
    133. }
    134. void swap(vector& v)
    135. {
    136. swap(_start, v._start);
    137. swap(_finish, v._finish);
    138. swap(_endOfStorage, v._endOfStorage);
    139. }
    140. iterator insert(iterator pos, const T& x)
    141. {
    142. assert(pos <= _finish);
    143. // 空间不够先进行增容
    144. if (_finish == _endOfStorage)
    145. {
    146. size_t size = size();
    147. size_t newCapacity = (0 == capacity())? 1 : capacity() * 2;
    148. reserve(newCapacity);
    149. // 如果发生了增容,需要重置pos
    150. pos = _start + size;
    151. }
    152. iterator end = _finish - 1;
    153. while (end >= pos)
    154. {
    155. *(end + 1) = *end;
    156. --end;
    157. }
    158. *pos = x;
    159. ++_finish;
    160. return pos;
    161. }
    162. // 返回删除数据的下一个数据
    163. // 方便解决:一边遍历一边删除的迭代器失效问题
    164. iterator erase(Iterator pos)
    165. {
    166. // 挪动数据进行删除
    167. iterator begin = pos + 1;
    168. while (begin != _finish)
    169. {
    170. *(begin - 1) = *begin;
    171. ++begin;
    172. }
    173. --_finish;
    174. return pos;
    175. }
    176. private:
    177. iterator _start; // 指向数据块的开始
    178. iterator _finish; // 指向有效数据的尾
    179. iterator _endOfStorage; // 指向存储容量的尾
    180. };
    181. }

    经典题目练习 

    1.杨辉三角OJ

    模拟;练一练二维vector 

    1. class Solution {
    2. public:
    3. vectorint>> generate(int numRows) {
    4. vectorint>> vv;
    5. vv.resize(numRows);
    6. for(size_t i=1;i<=numRows;i++)
    7. {
    8. vv[i-1].resize(i,0);
    9. vv[i-1][0]=1;
    10. vv[i-1][i-1]=1;
    11. }
    12. for(int i=0;isize();i++)
    13. {
    14. for(int j=0;jsize();j++){
    15. if(vv[i][j]==0)
    16. {
    17. vv[i][j]=vv[i-1][j]+vv[i-1][j-1];
    18. }
    19. }
    20. }
    21. return vv;
    22. }
    23. };

    2.删除排序数组中的重复项 OJ

     快慢指针:

    所谓快:不加条件判断的数组下标累计
    所谓慢:加上条件判断的数组下标累计

    1. class Solution {
    2. public:
    3. int removeDuplicates(vector<int>& nums) {
    4. int n=nums.size();
    5. if(n==0){
    6. return 0;
    7. }
    8. int fast=1,slow=1;
    9. while(fast
    10. {
    11. if(nums[fast]!=nums[fast-1]){
    12. nums[slow]=nums[fast];
    13. slow++;
    14. }
    15. fast++;
    16. }
    17. return slow;
    18. }
    19. };

    3. 数组中出现次数超过一半的数字 

    最优解:候选法 

    思想就是:如果两个数不相等,就消去这两个数,最坏情况下,每次消去一个众数和一个非众数,那么如果存在众数,最后留下的数肯定是众数(因为超过数组一半)。

    1. 假设cond为候选人,cnt为票数(要找到票最多的当选);
    2. 如果cnt为0,说明没有候选人或者该候选人票不够选不了;
    3. 否则,如果cnt > 0, 表示有候选人,如果当前数=cond,则++cnt,否则--cnt
    1. class Solution {
    2. public:
    3. int MoreThanHalfNum_Solution(vector<int> numbers) {
    4. int cond = 0;
    5. int cnt = 0;
    6. for (int i=0; isize(); ++i)
    7. {
    8. if (cnt == 0)
    9. {
    10. cond = numbers[i];
    11. ++cnt;
    12. }
    13. else
    14. {
    15. if (cond == numbers[i]) ++cnt;
    16. else --cnt;
    17. }
    18. }
    19. return cond;
    20. }
    21. };

    4.只出现一次的数字

    不需要额外空间的方法,就往位运算上想

    1. 交换律:a ^ b ^ c <=> a ^ c ^ b

    2. 任何数于0异或为任何数 0 ^ n => n

    3. 相同的数异或为0: n ^ n => 0

    1. class Solution {
    2. public:
    3. int singleNumber(vector<int>& nums) {
    4. int ret=0;
    5. for(auto e:nums)
    6. ret^=e;
    7. return ret;
    8. }
    9. };

    5.电话号码字母组合

     思路:

    由题意知就是把字母一一组合;

    1. 首先使用哈希表存储每个数字对应的所有可能的字母,然后进行回溯操作
    2. 假设输入“234”,进入递归,首先获得str第一个字符‘2’然后转成数字,取数字映射的字符串
    3. 开始遍历字符“abc”,刚取到‘a’时再进入递归取第二个字符‘3’,取数字映射的字符串“def”后开始遍历,以此类推我们的combineStr为“adg”
    4. 取到“adg”时就到顶了,利用di==digits.size()判断,将取到的组合数保存到retV并开始回溯;
    5. 由auto ch : str 我们会遍历“ghi”,按照上述同理方法得到“adh”,“adi”,然后回溯到第二次取‘e’,同理得“aeg”,“aeh”,“aei”
    6. 最终取到3*3*3种排列

    回溯算法用于寻找所有的可行解,如果发现一个解不可行,则会舍弃不可行的解。在这道题中,由于每个数字对应的每个字母都可能进入字母组合,因此不存在不可行的解,直接穷举所有的解即可。

    1. class Solution {
    2. string nums[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    3. public:
    4. void Combine(string digits,int di,string combineStr,vector& retV)
    5. {
    6. if(di==digits.size())
    7. {
    8. retV.push_back(combineStr);
    9. return;
    10. }
    11. int num=digits[di]-'0';
    12. string str=nums[num];
    13. for(auto ch:str)
    14. {
    15. Combine(digits,di+1,combineStr+ch,retV);
    16. }
    17. }
    18. vector letterCombinations(string digits) {
    19. vector retV;
    20. if(digits.empty())
    21. return retV;
    22. int i=0;
    23. string str;
    24. Combine(digits,i,str,retV);
    25. return retV;
    26. }
    27. };

    顺手打败全国的人~~ 

    6. 连续子数组的最大和  

    经典动态规划
    • step 1:可以用dp数组表示以下标 i 为终点的最大连续子数组和。
    • step 2:遍历数组,每次遇到一个新的数组元素,连续的子数组要么加上变得更大,要么这个元素本身就更大,要么会更小,更小我们就舍弃,因此状态转移为dp[i]=max(dp[i−1]+array[i],array[i])                                                                                  
    • step 3:因为连续数组可能会断掉,每一段只能得到该段最大值,因此我们需要维护一个最大值。
    1. class Solution {
    2. public:
    3. int FindGreatestSumOfSubArray(vector<int> array) {
    4. vector<int> dp(array.size(),0);
    5. dp[0]=array[0];
    6. int maxv=dp[0];
    7. for(int i=1;isize();i++)
    8. {
    9. dp[i]=max(dp[i-1]+array[i],array[i]);
    10. maxv=max(maxv,dp[i]);
    11. }
    12. return maxv;
    13. }
    14. };

  • 相关阅读:
    Mysql的主键UUID、自增ID、雪花算法到底该怎么选择?(荣耀典藏版)
    C# string为什么可以与int相加? string字符串拼接深入分析
    云计算及其应用知识点总结
    C++ 性能优化指南 KurtGuntheroth 第1章 优化概述
    Matlab之创建空数组的多种方法汇总
    Ollama:本地部署大模型 + LobeChat:聊天界面 = 自己的ChatGPT
    [C][文件操作][一][文件指针][文件的打开与关闭][文件的顺序读取接口]详细讲解
    4507. 子数组异或和
    黑洞优化算法(Matlab实现)
    怎么把录音转文字?只需三步,手把手教会你
  • 原文地址:https://blog.csdn.net/qq_61386381/article/details/125869840