今日小结——20190415(LeetCode日常+论文)

今天这篇文章主体部分是为我滴宝贝儿总结的,vector、map、set、iterator的常见用法和通俗理解!

1.vector

大概介绍一下vector是个啥,首先它是一种数据类型,类似于int double这种,然后被vector定义的类型,可以看做是一种数组,因为和一维数组的功能基本一样,只是多了很多内置函数,可以用来方便操作数组内的数!

基本操作:vector<int>  vec;  (因为vector是模板类,所以需要自带数据类型,这里的int就是定义的vec数组的数据类型,也就是这个数组有若干个int数据),比较好的一点就是不用定义大小,方便扩充

                   vector<int> vec(5);(定义一个大小为5的向量/数组)

                   vector<int>  vec(5,2);(定义一个大小为5的向量/数组,每个数的值都为2)

下面使用前面定义的vec来展示基本用法:

vec.size()(输出vec向量的大小,也就是数组的大小)

vec.empty()(判断是否为空,输出为0/1,一般用于if语句中作为判断条件)

vec.insert(vec.begin(),666)(把666插入到开头)

vec.insert(vec.begin(),6,666)(把666插入到开头前六个元素)

vec.push_back(666)(把666加入到vec向量中,类似于链表操作)

以及还有一个创建二维数组的用法:

vector<vector<int> >  vec2;(设置了一个二维数组,行是vector<int>类型,列是int类型)

vector<string> vec2;(设置了一个二维数组,行符合vector的所有函数特性,列符合string的所有特性)

比如:vector<string> vec2;那么vec2.size()就是行数,vec2[2].length()就是列数

2.map

大概介绍一下map,map也是STL中的一个容器,称为关联式容器,为啥叫关联式容器呢,因为他是处理一对一的数据,类似于函数,而且map内部算法是吧数据放在一个二叉树中,可以使得内部数据是有序的,关键来了,有序!!!这一点很好用。

map内部是key-value对应关系,key官方名称叫做键值,他的作用可以看做是一个索引,查找value所需要的一个外部接口,通过查key就可以找到数据。

对应关系:value  =map[key]

基本操作:map <int,string>  mymap;(int是key的数据类型,string是value的数据类型)

                  mymap[i]=arr[i];(key相当于数组arr的下标,value相当于arr的值)

                  mymap.count(key);(输出是0/1,表示下标为key的value在不在容器中)

                   mymap.find(key);(输出是指向key的迭代器,也就是value)

                   mymap.insert(pair<int,string>(666,"小可爱"));(使用pair插入key=666,value="小可爱")

tips:map中的元素是按照key值升序排列,这一点很重要哦,sort函数就不可以用啦!

3.iterator

说完map就得接着说迭代器,因为他俩始终是绑定的,大概说一下啥是迭代器,我们平时访问数组类型都是通过下标访问,包括C++特有的vector也是通过下标访问,但是在C++中提供了更为方便的一种容器,那就是迭代器,所以我们可以把迭代器看做是指针访问(内部其实也是这么写的)。

基本操作:容器类名::iterator  迭代器名(例如map::iterator  it;    vector::iterator  it;等等,准确的说这个叫做正向迭代器,反向的没用过就不说啦)

                   vector<int>::iteractor  it.begin()(迭代器指向vector第一个元素)

                   vector<int>::iteractor  it.end()(迭代器指向最后一个元素的下一个位置,这里切记!!end()是最后一个元素的下一个,超出了范围,但是作为一个闲置位还是很有必要存在的!)

迭代器也满足指针访问的几乎所有用法,当指针就完事儿了!

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

                                                              下面重要的来了!!!

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

 关于那天宝贝儿用的迭代器方法做那道题,后来想想其实是有道理的,代码可能写的有问题

首先,之前如果用的是map容器,那么进行迭代器元素删除,后面元素不会发生前移,因为map是二叉树结构,删除结点不会导致整体变化,除非在每次删除后主动写iteractor++,那么就会顺延,但是此种操作较为麻烦,我觉得最好的方法是直接用vector向量,比如说你现在第一行提取出来了str[1],str[5],str[9],下面要删掉这三个,并且保持序号全部前移

vector<string> str;
vector<string>::iteractor it;
it=find(str.begin(),str.end(),str[1]);//从头到尾寻找这个元素
str.erase(it);//erase是删除操作,删除后,后续元素在vector中前移

 这是目前我能想到的方法,操作起来还是要写很多的,但是方法很对!!

 4.set

概念基本和map差不多,但是set不能直接修改内部数据,而且set定义的数组输出是是自动升序排列,且删除重复元素!这个也要留意,这个方法用在提取最大值时候一步就做出来了,所以感叹集成函数的牛批。。。

map是有key+value的数据储存方式,但是set只有关键字也就是值,其余函数用法和map一毛一样,所以只要记住他和map的区别就行,用起来根据不同需求选择!

 5.LeetCode

1)#14 最长公共前缀

此题比较简单,不作分析,直接贴代码

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if(strs.size()==0)
        {
            return "";
        }
        for(int i=0;i<strs[0].size();i++)
        {
            char c=strs[0][i];
            for(int j=1;j<strs.size();j++)
            {
                if(i==strs[j].size()||strs[j][i]!=c)
                    return strs[0].substr(0,i);
            }
        }
        return strs[0];
    }
};

 2)#15 三数之和

这个题差点做的崩了,测试了三循环方法,超时。。。测试了确定两个数循环第三个数的方法,速度慢且内存占用异常大。。。后来想到了排序,就想到了set,所以就用STL优化了第二种解法,虽然还是很长,但是也算优化了!

 

首先因为只是找出来三个数,所以我们不用管顺序,那就直接sort排序一波!然后先找一下最大最小值,如果最大值都没0大,或者最小值都大于0.那肯定不存在三数和为零的情况,如果最大最小值一样,也就是全部元素一样,那除了全为0其他就可以全部舍弃了,这个筛选就节约了大量时间!

下面进入主题部分,使用双循环,第一个循环是第一个数下标,第二个是第二个下标,然后利用map的特性,找到值为-(nums[i]+nums[j])的那一个key,返回给其迭代器,如果这个key不是不存在也不是前两个数,那么就把这三个数放入新建的set容器中等待输出,此法我叫他流氓寻找法。。。合理利用map的find函数嘛嘻嘻嘻,全部for完了之后,再把set中的结果输出就好啦

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int> > result;
        if(nums.size()<3)
            return result;
        sort(nums.begin(),nums.end());
        
        map<int,int> m;
        set<vector<int> > se;
        int minNum=nums[0],
        maxNum=nums[0];
        for(int i=0;i<nums.size();i++){
            minNum=min(minNum,nums[i]);
            maxNum=max(maxNum,nums[i]);
            m[nums[i]]=i;
        }
        if(maxNum==minNum){
            if(minNum==0){
                vector<int> t;
                t.push_back(0);
                t.push_back(0);
                t.push_back(0);
                result.push_back(t);
            }
            return result;
        }
        if(maxNum<0||minNum>0){
            return result;
        }
        map<int,int>::iterator it;
        for(int i=0;i<nums.size();i++){
            for(int j=i+1;j<nums.size();j++){
                if(i<j){
                    if(nums[i]+nums[j]+minNum>0||nums[i]+nums[j]+maxNum<0){
                        continue;
                    }
                    it=m.find(-(nums[i]+nums[j]));
                    if(it!=m.end()&&it->second>j){
                        vector<int> t;
                        t.push_back(nums[i]);
                        t.push_back(nums[j]);
                        t.push_back(it->first);
                        se.insert(t);
                    }
                }
            }
        }
        set<vector<int> >::iterator sit=se.begin();
        
        for(;sit!=se.end();sit++){
            result.push_back(*sit);
        }
        return result;
    }
};

 

 

 

 

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值