[TOC]
什么时候再括号里加限制条件,什么时候在for循环体内加限制条件
这两者的区别在哪 括号里的是必须条件,不满足条件直接结束函数
class xxx{
}; //!!!!!!!!!!!!!!!!!!!
string word = s.substr(startIndex,i-startIdex+1);
// 第一个参数代表起始位置,包含起始位置本身
//第二个参数代表从起始位置开始数多少位元素
如果容器里没有元素的初始化,O(1)
如果容器内有元素,O(n),因为实际的初始化过程都是拷贝的过程
vector<vector<int>> dp(m,vector<int>(n,0));
vector<vector<int>> buckets(k+1); //只定义第一层长度
sort(nums.begin(),nums.end());
vector.back();
vector.front();
//vector支持.front() 但是不支持pop_front()
==顺序容器没有find方法?只有关联容器有吗?关联容器为什么要提供这种方法?为什么顺序容器又不提供?==
==关联容器中key的顺序与插入顺序并不一致==
unordered_set.find(x) 查找x在set中是否存在,不存在返回尾迭代器,存在呢?返回第一个key为x的迭代器 find时间复杂度 查询效率O(1) 增删效率O(1)
unordered_set.insert(x) 插入x 返回一个pair,其第一个元素是指向刚插入元素的迭代器,第二个元素是bool类型,若插入成功(对应容器中不存在key),返回true;若插入失败(对应容器中已存在key),返回false。
unordered_set.erase(x) 删除x 返回删除的最后一个元素的下一个元素的迭代器。
==为什么unordered_set的查询和增删效率这么高?==
https://blog.csdn.net/fjhugjkdsd/article/details/108091424
底层结构使用一个哈希函数 hash(key) = position 将key与元素存储位置建立一个映射
因此在查找,增删时,我=都只需要调用hash(key),即可知道该元素(或即将被存储的)的存储位置
利用vector的一对迭代器即可构造unordered_set
unordered_set<string> wordSet(wordDict.begin(),wordDict.end());
signed int能够表示的数据范围:-2147483648~2147483647
利用迭代器范围构造
vector<int> left(postorder.begin(),postorder.begin() + border);
与生成子字符串进行对比,==字符串是否可以用上面的方法?==
string word = s.substr(startIndex,i-startIdex+1);
// 第一个参数代表起始位置,包含起始位置本身
//第二个参数代表从起始位置开始数多少位元素
- 写一个ListNode
要求:两个成员变量,val和next,构造函数
class ListNode{
public:
int val;
ListNode *next;
ListNode(int val=0,ListNode *next = nullptr):val(val),next(next){}
};
//简单的把public理解为让任何人可以使用的方法,即接口函数;而private为不想让别人使用的内部细节
ListNode *head = &ListNode(val);
不可以,构造函数创造临时变量,并未给其分配内存地址
正确的做法是:
ListNode *head = new ListNode(val);
但是这样的话,谁来负责销毁这个node呢?
其实对于本题来说,销毁链表本事就可以了
这样可以吗?
ListNode node = ListNode(val);
ListNode *head = &node;
在尾部插入可以使用重载的运算符 “+=”
string path;
path +="hello";
path +=" ";
path +="world"
string to_string()
int stoi(int) //将字符串转换为int类型,注意这里类型需要匹配
还没全部验证,最起码在string和vector中,使用size()函数返回的是其容器内自定义的类型string::size_type
和vector<int>::size_type
它是一个无符号类型整数。
当我们将无符号类型与有符号类型进行运算时, 编译器会自动将所有数据全部看做无符号类型的数字。
int,short,long,long long默认都是有符号整型。
unsigned a = 0;
unsigned b = a-1; //b为4294967295
int c = a-1; //c为-1
在上面的例子中,a-1是无符号运算,得到4294967295(4字节全1),因此b也为4294967295,但是c是有符号类型,对于int类型,全1表示的正是-1。
因此,我们发现,当数组为空数组时,单独地使用nums.size()-1是危险的,因为我们潜意识里将这个表达式等同于-1来使用。
给我们的启示:
- 当单独使用nums.size()-1时,确保其一定不为空数组。在可以的情况下,使用<nums.size()而避免使用<=nums.size()-1
- 或者避免单独使用nums.size()-1,使用一个int型变量来代替数组的大小
int size = nums.size(); //使用int类型表示数组长度是安全的
for(int i=0;i<size-1;i++){
}
==以前特别经常使用nums.size()-1,尤其是在for循环中,也没办法一一排查了,后面写代码的时候注意==
#if 0
#endif
用于注释块状代码
~ & | ^ 位反 位与 位或 位异或
! && || 逻辑非 逻辑与 逻辑或
pow(2,a); //表示2的a次方,顺序不可颠倒,注意返回值是double的,类型转
三元条件运算符可以用做左值,也可以用作右值,这取决与你。格式如下:
eg.
maxLen = maxLen>ap? maxLen:ap;
- 三元条件运算符的优先级很低,因此使用时最好加上括号,以避免不必要的麻烦。
- 虽然它能提高我们的代码简洁度,但最好不要嵌套两层以上,这会给阅读造成极大的压力。
- 我们在:两侧不能使用列表构造的方式对vector进行值传递
vector<int> point= {0,1};
point = point[1]>(j-i+1)? point:{i,j-i+1}; //compile error!
它的一个常用场景是更新极值,当然,还有另一种方式更加的容易理解,即使用max()
,min()
函数。
- 两个用于比较的实参需要的拥有相同的类型
int right = min(i+k-1,s.size()-1);
//由于s.size()的返回类型为string:size_type而并不是int
//因此编译错误
之所以需要是相同的类型,是因为min和max的泛型算法定义中仅使用了一个泛型T,而并没有使用两个。
template<class T> const T& min(const T& a, const T& b);
template<class T, class Compare>
const T& min(const T& a, const T& b, Compare comp);
template<class T> const T& max(const T& a, const T& b);
template<class T, class Compare>
const T& max(const T& a, const T& b, Compare comp);
至于为什么不使用两个类型,而非要规定一个类型,原因在这里有详细的分析:https://stackoverflow.com/questions/56725358/why-c-compiler-gives-error-when-using-stdmax-function-for-two-different
- 可以用于比较多个值的大小,只需要将几个实参用{}括起来即可。
template< class T >
T min( std::initializer_list<T> ilist );
template< class T >
constexpr T min( std::initializer_list<T> ilist );
template< class T, class Compare >
T min( std::initializer_list<T> ilist, Compare comp );
template< class T, class Compare >
constexpr T min( std::initializer_list<T> ilist, Compare comp );
- min和max实际上属于泛型算法,在使用时需要包含头文件
<algorithm>