1. 图:
深度优先搜索(并查集)PAT甲级1034 Head of Gang
英文记录:
1. duplicates重复
2. in lexicographic order.(用字典顺序)
3. modifying the input array in-place(原地修正输入数组)
4. non-overlapping intervals无重叠的区间
5. fraction分数、小数
6. 构建树时,return的界限包含=时,表示右边界不包含;不包含=时,表示右边界包含。
重点:
1. 二分查找(左边界、右边界)、二叉树的前序/中序/后序遍历重构树、
2. int和string相互转化:#include<sstream>; stringstream ss;
3. 哈希:map
#include <map>
#include <algorithm>
vector<vector<string>> groupAnagrams(vector<string>& strs) {
//map初始化
map<char,int> mymap={{'a',0},{'b',0},{'c',0},{'d',0},{'e',0},{'f',0},{'g',0},{'h',0},{'i',0},{'j',0},{'k',0},{'l',0},{'m',0},{'n',0},{'o',0},{'p',0},{'q',0},{'r',0},{'s',0},{'t',0},{'u',0},{'v',0},{'w',0},{'x',0},{'y',0},{'z',0}};
//利用map进行key(stirng),value(index)的记录
map<string, int> mymap;//定义
//
for (int i = 0; i < strs.size(); i++) {
//
sort(str.begin(), str.end()); //string排序
if (mymap.find(str) == mymap.end()) {//find函数寻找字符串key键,没找到等于mymap.end
mymap[str] = index;//赋值
//
}
//
}
//
}
需要注意的点:
浮点数最好用double,不要用float。double kk; scanf("%lf",&kk);
1. 极端情况,直接判断后返回值
2. 对vector等是否为空的情况进行判断,避免后续空指针报错
3. VS:【调试】-》【窗口】-》【局部变量】
图:
1. 深度优先搜索(递归、可计算连通子图个数)+广度优先搜索(栈,可解决层高问题)PAT1021题
2. 博客【PAT1021】邻接矩阵VS邻接表
字符串:
string可以用等号比较,char数组用strcmp进行比较
s1.insert(0, 4 - s1.length(), '0'); // 在位置为0的地方补足数字
输出空格:
PAT中strcpy和strlen函数需要包含头文件#include<string.h>
1. string.substr(start,length) VS string.substring(start,end)
2. string字符遍历或者数组遍历记得内层while也加边界判断
数组:
1. set的insert可辨别重复值不插入。
leetCode18四数之和 set<vector<int>> res;转化为vector<vector<int>>(res.begin(),res.end());
2. 递归要是超时,可以用dp数组记录已经计算过的值
string s1;getline(cin,s1);
当作为vector的res的size=0,判断下面for条件时,i=0;i<-1无法跳出循环,需要改为(i+1)<res,size()
for (int i = 0; i < res.size()-1; i++) {
printf("%d ", res[i]);
}
1. 双指针可以减少遍历,二分查找能够减少遍历时间
2. int p[1000]; memset(p,0,sizeof(p)); #include<cstring>
3. for(iter=nums.begin();iter!=nums.end();iter++) 迭代器对vector的遍历
vector<int>::iterator iter_end=iter+1; iter_end=nums.erase(iter_end); //erase函数,指向被删除元素的下一个元素
4. vector中元素为pair的用法:vector<pair<int,int>> vec; int a=vec[i].first; int b=vec[i].second;
5. int和string相互转化
string s = to_string(a);
int s1c = atoi(s1.c_str());
#include <iostream>
#include <string>
using namespace std;
int main() {
//int to string 不需要头文件(int,char *,int radix)
/*
int aa = 30;
char s[8];
_itoa(aa, s, 10);
cout << s << endl;
*/
//int转化为string:先用char数组,再用(string)强制转化
int aa=10;
char s[8];
string s_copy="123";
sprintf(s, "%d", aa);
string s2 = (string)s;
cout << s2+"->"+s_copy<<endl;
//string转化为int,不要忘记加&号
int aa1;
//char s1[8]="1023";
string s1= "1023";
//.c_str()为从string转化为cconst char*
sscanf(s1.c_str(), "%d", &aa1);
cout <<aa1;
system("pause");
return 0;
}
6. 8/9个排序算法归纳
#include <iostream>
#include <string>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
//选择排序
//找到一个后续元素中最小的元素与之交换
void selectionSort(vector<int> &vec) {
for (int i = 0; i < vec.size()-1; i++) {
int smallIndex = i;
for (int j = i + 1; j < vec.size(); j++) {
if (vec[j] < vec[smallIndex])
smallIndex = j;
}
if (smallIndex != i) {
int temp = vec[i];
vec[i] = vec[smallIndex];
vec[smallIndex] = temp;
}
}
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
}
//交换排序
//第一轮定位数组第一个,扫描后续元素,遇到比他小的,即交换(这里指升序)
void exchangeSort(vector<int> &vec) {
for (int i = 0; i < vec.size()-1; i++) {
for (int j = i + 1; j < vec.size(); j++) {
if (vec[j] < vec[i]) {
int temp = vec[i];
vec[i] = vec[j];
vec[j] = temp;
}
}
}
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
}
//冒泡排序
void bobbleSort(vector<int> &vec) {
for (int i = 1; i < vec.size(); i++) {
bool flag = false;
for (int j = 0; j < vec.size()-i; j++) {
if (vec[j] > vec[j + 1]) {
int temp = vec[j];
vec[j] = vec[j+1];
vec[j+1] = temp;
//插入哨兵的bobbleSort
flag = true;
}
}
if (flag) break;
}
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
}
//插入排序
void insertionSort(vector<int> &vec) {
for(int i = 1; i < vec.size(); i++) {
int temp = vec[i];
int j = i;
//将大于temp的元素全体向后移动一位,注意这里是j-1
//带哨兵:vec[0]存放待插入元素,防止数组下标越界,将j>0与A[j]>temp结合成只有一次比较A[j]>A[0]
while (j > 0 && vec[j-1] > temp) {
vec[j] = vec[j - 1];
j--;
}
vec[j] = temp;
}
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
}
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
return;
}
//快排
void quickSort(vector<int> &vec, int left, int right) {
//size=1,不要用vec.size()去判断,因为vec.size()递推时不变
if ((right-left) == 0)
return;
//size=2
else if ((right-left) == 1) {
if (vec[left] > vec[right])
swap(vec[left], vec[right]);
return;
}
else {
//为了解决mid左右比vec[mid]大或小数量不一样的情况,将vec[mid]与vec[left]交换
int mid = (left + right) / 2;
swap(vec[mid], vec[left]);
int L = left+1;
int R = right;
while (L < R) {
while (L < R&&vec[L] < vec[left]) L++;
while (L<R&&vec[R] > vec[left]) R--;
if (L < R)
swap(vec[L],vec[R]);
}
//L=R
if(vec[L]>vec[left])
swap(vec[left], vec[L-1]);
//当选取到的mid刚好是区间最大值时
else
swap(vec[left], vec[L]);
quickSort(vec, left, L-1);
quickSort(vec, L, right);
return;
}
}
//归并排序--并
void merge(vector<int>& vec,int first,int mid,int last) {
vector<int> temp;
//把vector[first]~vector[mid-1]和vector[mid]~vector[last-1]的数组合并
int i = first;
int j = mid;
while (i < mid&&j < last) {
if (vec[i] < vec[j]) {
temp.push_back(vec[i]);
i++;
}
else {
temp.push_back(vec[j]);
j++;
}
}
while (i < mid) {
temp.push_back(vec[i]);
i++;
}
while (j < last) {
temp.push_back(vec[j]);
j++;
}
int index = 0;
for (int i = first; i < last; i++) {
vec[i] = temp[index];
index++;
}
return;
}
//归并排序--拆
void mergeSort(vector<int> &vec,int fir,int last) {
if (fir >= last - 1)
return;
int mid = (fir + last) / 2;
mergeSort(vec, fir, mid);
mergeSort(vec, mid, last);
merge(vec, fir, mid, last);
}
//调整堆
void adjustHeap(vector<int> &vec, int left, int right) {
//令根与其左右子女进行比较,较大者调整至根节点
//根、左子女、右子女坐标分别为i,2*i+1,2*i+2
int temp = vec[left];
for (int i = 2 * left + 1; i < right; i=2*i+1) {
if (i + 1 < right && vec[i] < vec[i + 1]) {
i++;
}
if (vec[i] > temp) {
swap(vec[i], vec[left]);
left = i;
}
else {
break;
}
}
}
//堆排序
void HeapSort(vector<int> &vec) {
//先进行建堆处理,最后一个非叶节点的序号为vec.size()/2-1
for (int i = vec.size() - 1; i >= 0; i--)
adjustHeap(vec, i, vec.size());
for (int i = vec.size()-1; i >=0; i--) {
//交换第一个元素和最后一个元素
swap(vec[i], vec[0]);
//进行最大堆的调整
adjustHeap(vec,0,i);
}
}
//基数排序
void RadixSort(vector<int> &vec,int n) {
queue<int> q[10];
int radix = 1;
for (int i = 1; i <= n; i++){
//放到queue中
for (int j = 0; j < vec.size(); j++) {
q[vec[j] / radix % 10].push(vec[j]);
}
int k = 0;
for (int j = 0; j <10; j++) {
while (!q[j].empty()) {
vec[k++] = q[j].front();
q[j].pop();
}
}
radix = radix * 10;
}
}
int main() {
//主要这里排序目标为升序
vector<int> vec = { 1,10,9,8,3,7,5,2,6,4,991,56,365,578,23,4};
//selectionSort(vec); //不稳定
//exchangeSort(vec); //不稳定
//bobbleSort(vec); //不稳定
//insertionSort(vec); //稳定
//希尔排序:无代码,设置步长进行排序
//快排:选中vec[mid],将mid左边比vec[mid]大的mid右边比vec[mid]小的进行交换
//快排不稳定
/*
quickSort(vec,0,vec.size()-1);
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
*/
//归并排序: 并---两个有序序列归并成一个有序序列,稳定排序
/*
mergeSort(vec, 0, vec.size());
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
*/
//堆排序相对较为复杂,首先需要进行 通过自下而上地对非叶节点进行adjustHeap来建立最大堆
//最大堆的根节点即为数组的最大值,将最大值与最后一个元素进行交换。这时,最后一个元素即为数组的最大值
//Heap的根节点进行调换后需要重新进行adjustHeap堆调整操作
//最大堆最后数组升序输出 不稳定
/*
HeapSort(vec);
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
*/
//基数排序:
//取最大值,计算最大值的位数
/*
int max = vec[0];
int i = 0;
for (int i = 1; i < vec.size();i++) {
if(max<vec[i])
max = vec[i];
}
//20--2位数--radix=100--j=2;
int j = 1;
int radix = 10;
while (max / radix != 0) {
radix = radix * 10;
j++;
}
cout << max<<" "<<j << endl;
RadixSort(vec, j);
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;
*/
system("pause");
return 0;
}