链表
1.原地翻转
保存下一个节点
改变指向
向下移动
ListNode* reverseList(ListNode* head){
ListNode* p=nullptr,*tmp;
while(head){
tmp=head->next;
head->next=p;
p=head;
head=tmp;
}
return p;
}
2.链表的环
快慢指针法:fast每次移动两个,slow移动一个。
首先fast和slow一起从head移动,如果fast到达终点(即无法再移动了,说明没有环),如果fast和slow相遇,则有环。
求环的长度:
第一次相遇后fast不动,slow继续动,直到和fast再次相遇,走过的距离即为环长。
求环的起始点:
第一次相遇后,fast移到head,且速度调整为和slow一样,再次相遇就是环的起始点。
证明:
如图所示,第一次相遇,slow走过的路程为s=p+m+al(l为环长),fast走过的路程为2s=p+m+bl,可得s=(b-a)l,也就是说,p+m是环长的整数倍。相遇后,fast调整速度为1,且到head开始。fast走到M点时(这个是在fast调整到head后的第n次相遇),slow也在M点,此时可以让fast和slow回退到P点,此时为第一次相遇。
二叉树的非递归遍历方法:
1.前序遍历
采用栈,由于栈的先进后出,所以先压入右孩子,再压入左孩子。
class Solution:
def preorderTraversal(self, root):
ret, stack = [], [root]
while stack:
node = stack.pop()
if node:
ret.append(node.val)
#注意压入栈的顺序,先压入右孩子,再压入左孩子
stack.append(node.right)
stack.append(node.left)
return ret
2.中序遍历
栈。先压左,左到头了,开始弹出,一边弹一边压右孩子。
class Solution:
def inorderTraversal(self, root):
ret, stack = [], []
while stack or root:
if root:
stack.append(root)
root = root.left
else:
temNode = stack.pop()
ret.append(temNode.val)
root = temNode.right
return ret
string和int互相转化
string s="123";
int a=atoi(s.c_str());
string ss = to_string(a);
如果string不是数字形式的则转换结果为0。
vector:
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
vector<int> v{ 3, 1, 4 };
auto it = v.begin();//第一个元素
auto end = v.end();//最后一个元素的后一个
auto nx = next(it, 2);
auto p = prev(it);//begin 的prev, 为空;end的next为空
cout << *it << ' ' << *nx << '\n';
}
set:
插入:insert
stack:
top(), pop(), push(), empty(), size()
queue:
front(), pop(), push(), empty(), size()
map:
访问key,val
map<int, int> m;
for(auto a:m)
cout<<a.first<<a.second<<endl;
//find用法
map<int,int>::iterator it=m.find(1);
if(it==m.end())
cout<<"not found"<<endl;
else
cout<<it->first<<end;
map按照自己规定的方式排序
struct CmpByKeyLength {
bool operator()(const string& k1, const string& k2) {
return k1.length() < k2.length();
}
};
int main(){
map<string, int, CmpByKeyLength > mapStudent; //这里注意要换成自己定义的compare
mapStudent[“LiMin”]=90;
mapStudent[“ZiLinMi”]=72;
mapStudent[“BoB”]=79;
map<string, int>::iterator iter=mapStudent.begin();
for(iter=mapStudent.begin();iter!=mapStudent.end();iter++){
cout<first<<" "<second<<endl;
}
return 0;
}
map按照value排序
struct CmpByValue {
bool operator()(const PAIR& lhs, const PAIR& rhs) {
return lhs.second < rhs.second;
}
};
int main(){
map<string, int> name_score_map;
name_score_map["LiMin"] = 90;
name_score_map["ZiLinMi"] = 79;
name_score_map["BoB"] = 92;
name_score_map.insert(make_pair("Bing",99));
name_score_map.insert(make_pair("Albert",86));
/*把map中元素转存到vector中*/
vector<PAIR> name_score_vec(name_score_map.begin(), name_score_map.end());
sort(name_score_vec.begin(), name_score_vec.end(), CmpByValue());
/*sort(name_score_vec.begin(), name_score_vec.end(), cmp_by_value);也是可以的*/
for (int i = 0; i != name_score_vec.size(); ++i) {
cout<<name_score_vec[i].first<<" "<<name_score_vec[i].second<<endl;
}
return 0;
}
map排序:https://blog.youkuaiyun.com/chengqiuming/article/details/89816566
string:
逆序reverse(s.begin(), s.end())
交换函数:s1.swap(s2)
find_first_of(s[i]), find_last_of(s[i]) //找到第一个、最后一个出现的位置
find(s[i],pos)//从pos开始找s[i]第一个出现的位置,pos默认为0
cin ,cout:
字符串无空格:string s; cin>>s;
字符串带空格:getline(cin,s)
字符数组:char a[100]; gets(a);
素数判别:
//排除法:如果i是素数,那么i的倍数都不是素数
bool sushu(int a)
{
for(int i=2;i<=sqrt(a);++i)
{
if(a%i==0)
return false;//不是素数
}
return true;//是素数
}
int countPrimes(int n) {
vector<int> a(n,0);//0表示是素数
int i,j,cnt=0;
for(i=2;i*i<n;++i)//直观来看,i<n是终止条件,经过优化,可以i*i<n
{
if(sushu(i))
{
for(j=i*i;j<n;j+=i)//直观来看,可以从2i起始,这里从i*i起始,是优化过的
a[j] = 1;
}
}
for(i=2;i<n;++i)
{
if(a[i]==0)
++cnt;
}
return cnt;
}
螺旋矩阵
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n,vector<int>(n,0));
int x1=0,y1=0,x2=n-1,y2=n-1,i,j;
int a=1;
while(x1<=x2&&y1<=y2)
{
for(i=y1;i<=y2;++i)
{
res[x1][i]= a++;
}
for(i=i=x1+1;i<=x2;++i)
res[i][y2] = a++;
/*
for(i=y2-1;i>=y1+1;--i)
res[x2][i] = a++;
for(i=x2;i>=x1+1;--i)
res[i][y1] = a++;
*/
//如果是矩阵而不是方阵,那么可能存在重复打印的情况,因此要做如下判断:
if(x1<x2&&y1<y2)
{
for(i=y2-1;i>=y1+1;--i)
res[cnt++] = matrix[x2][i];
for(i=x2;i>=x1+1;--i)
res[cnt++] = matrix[i][y1];
}
x1++,y1++,x2--,y2--;
}
return res;
}
};
原地翻转数组,所有元素向右移动k个单位
void reverse(vector<int>& nums, int i, int j){
while(i<j){
int temp=nums[i];
nums[i++]=nums[j];
nums[j--]=temp;
}
}
void rotate(vector<int>& nums, int k) {
int n=nums.size();
k%=n;
reverse(nums,0,n-1);
reverse(nums,0,k-1);
reverse(nums,k,n-1);
BFS DFS
vector<bool> visit(n,false);
for(int i=0;i<n;++i)
{
if(!visit[i])
dfs(i);
}
void dfs(int i)
{
visit[i] = true;
cout<< i << " ";
for(int v=0;v<n;++v)
{
if(!visit[v] && G[v][i]==1)
{
dfs(v);
}
}
}
vector<bool> visit(n, false);
queue<int> q;
for(int i=0;i<n;++i)
{
if(!visit[i])
{
visit[i] = true;
cout<< i << " ";
q.push(i);
while(!q.empty())
{
int a = q.front();
q.pop();
for(int j=0;j<n;++j)
{
if(!visit[j] && G[a][j]==1)
{
visit[j] = true;
q.push(j);
cout << j << " ";
}
}
}
}
}
链表排序(归并排序)
ListNode* sortList(ListNode* head) {
return sortGuibing(head);
}
ListNode* sortGuibing(ListNode* head)
{
if(!head || !head->next)
return head;
ListNode* pre = head;
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next)
{
fast = fast->next->next;
pre = slow;
slow = slow->next;
}
pre->next = nullptr;
ListNode* l = sortGuibing(head);
ListNode* r = sortGuibing(slow);
return merge(l, r);
}
ListNode* merge(ListNode* head1, ListNode* head2)
{
ListNode* ya = new ListNode(-1);
ListNode *tmp=ya, *tmp1=head1, *tmp2=head2;
while(tmp1 && tmp2)
{
if(tmp1->val <= tmp2->val)
{
tmp->next = tmp1;
tmp1 = tmp1->next;
}
else
{
tmp->next = tmp2;
tmp2 = tmp2->next;
}
tmp = tmp->next;
}
if(tmp1)
tmp->next = tmp1;
if(tmp2)
tmp->next = tmp2;
return ya->next;
}
};