944 Delete Columns to Make Sorted && vector使用

涉及到两层循环,数组的遍历和字母的遍历。

1、刚开始是外循环数组,再判断字母,这样在判断的时候需要标记不符合条件的字母位置,这样数组循环时,被标记的字母位置不需要加入比较,因此需要额外的数组来记录不符合的位置。

  // The two-level loop order is important
  int minDeletionSize(vector<string>& A) {
    vector<int> res;
    vector<int> pos;
    for (int j=0; j < A[0].size(); ++j) {
      pos.push_back(j);
    }
    for (int i=0; i < (A.size()-1); ++i) {
      for (int j=0; j < pos.size(); ++j) {
        if (A[i][pos[j]] > A[i+1][pos[j]]) {
          res.push_back(pos[j]);
          pos.erase(pos.begin() + j);
          j--;
        }
      }
    }
    return res.size();
  }

2、先外循环位置,再字母 

  int minDeletionSize1(vector<string>& A) {
    int res = 0;
    int len = A[0].size();
    for (int i=0; i < len; ++i) {
      for (int j=0; j < (A.size()-1); ++j) {
        if (A[j][i] > A[j+1][i]) {
          ++res;
          break;
        }
      }
    }
    return res;
  }

两种方法差距还是很大的。

3、涉及到vector的erase,顺便记录下vector的用法

一、vector 的初始化:

1、vector<int> a(10); //定义了10个整型元素的向量,没有给出初值,其值是不确定的。
2、vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
3、vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
4、vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素,包含begin不包含end
5、int b[7]={1,2,3,4,5,9,8};//用数组来创建a向量,可以指定begin和end,包含begin不包含end
vector<int> a(b,b+7); 

二、vector对象的操作

1、a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
2、a.assign(4,2); //是a只含4个元素,且每个元素为2
3、a.back(); //返回a的最后一个元素
4、a.front(); //返回a的第一个元素
5、a[i]; //返回a的第i个元素,当且仅当a[i]存在,小心越界
   a.at(0); // 会进行下标越界检查,但是慢
6、a.clear(); //清空a中的元素
7、a.empty(); //判断a是否为空,空则返回ture,不空则返回false
8、a.pop_back(); //删除a向量的最后一个元素
9、a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)
10、a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
11、a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
12、a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5。如a为1,2,3,4,插入元素后为1,5,5,5,2,3,4
13、a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第4个元素到第6个元素(不包括b+6),如b为1,2,3,4,5,9,8,插入元素后为1,4,5,9,2,3,4,5,9,8
14、a.size(); //返回a中元素的个数;
15、a.capacity(); //返回a在内存中总共可以容纳的元素个数
16、a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
17、a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
18、a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100。这种操作只有在需要给a添加大量数据的时候才显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能) 
19、a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
20、a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<

几点说明:

1)14、15区别和16、18区别:

size是当前vector容器真实占用的大小,也就是容器当前拥有多少个容器。

扫描二维码关注公众号,回复: 6191563 查看本文章

capacity是指在发生realloc前能允许的最大元素数,即预分配的内存空间。

使用resize(),容器内的对象内存空间是真正存在的。

使用reserve()仅仅只是修改了capacity的值,容器内的对象并没有真实的内存空间(空间是"野"的)。

2)不知道数组size的情况下,使用[]操作符访问容器内的对象,会出现数组越界的问题,一般使用.at();。

下标[]赋值会显示SIGSEGV段错误,越界错误. 
at赋值会显示 terminate called after throwing an instance of ‘std::out_of_range’

c++标准不要求vector::operator[]进行下标越界检查,原因是为了效率,总是强制下标越界检查会增加程序的性能开销。

相关引申:

针对capacity这个属性,STL中的其他容器,如list map set deque,由于这些容器的内存是散列分布的,因此不会发生类似realloc()的调用情况,因此我们可以认为capacity属性针对这些容器是没有意义的,因此设计时这些容器没有该属性。

参考:

https://www.cnblogs.com/Nonono-nw/p/3462183.html

https://blog.csdn.net/yxccc_914/article/details/54846003
https://blog.csdn.net/u013575812/article/details/51171135 

猜你喜欢

转载自blog.csdn.net/huanucas/article/details/89154676