1.字符串
(1)字符串转化为整数

    int StrToInt(string str) {
        int size=str.size();
        if(size==0)
            return 0;
        int i=0,sign=1,result=0;
        while(str[i]==' ')
            i++;
        if(str[i]=='+')
            i++;
        if(str[i]=='-'){
            i++;
            sign=-1;
        }
        while(i<size){
            if(str[i]>='0'&&str[i]<='9')
                result=result*10+(str[i]-'0');//重点!!
            else
                return 0; 
            i++;
        }
        return result*sign;
    }

(2)字符串排列:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则按字典序打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

   string result;
    vector<string> allresult;
    vector<string> Permutation(string str){
        if(str.size()==0)
            return allresult;
        PermutationCore(str,0);
        sort(allresult.begin(),allresult.end());//注意sort的用法
        return allresult;
        }
    void PermutationCore(string str,int n){//确定第n个数
        int size=str.size();
        if(n==size-1){
            allresult.push_back(str);
            return;
        }
        for(int i=n;i<size;i++){
            if(i==n||str[n]!=str[i]){//一定要记住第一个也得进去
                char temp=str[n];
                str[n]=str[i];
                str[i]=temp;
                PermutationCore(str,n+1);
            }
        }

(3)第一个只出现一次的字符

int FirstNotRepeatingChar(string str) {
        if(str.length()==0)
            return -1;
        const int tableSize=256;
        unsigned int hashTable[tableSize];
        for(unsigned int i=0;i<tableSize;++i)
            hashTable[i]=0;
        int pHashKey=0;
        while(str[pHashKey]!='\0')
            hashTable[str[pHashKey++]]++;
        pHashKey=0;
        while(str[pHashKey]!='\0'){
            if(hashTable[str[pHashKey]]==1)
                return pHashKey;
            pHashKey++;
        }
        return -1;
    }

2.数组
(1)排序
图片说明

//快速排序
//平均时间复杂度:O(NlogN)
//最坏情况复杂度:O(N^2)
//不稳定排序
void quiksort(vector<int> &numbers,int start,int end){
        if(start>=end)
            return;
        int povit=numbers[start];
        int p1=start,p2=end;
        while(p1<p2){
            while(p1<p2&&numbers[p2]>=povit)
                p2--;
            if(numbers[p2]<povit)
                numbers[p1++]=numbers[p2];
            while(p1<p2&&numbers[p1]<=povit)
                p1++;
            if(numbers[p1]>povit)
                numbers[p2--]=numbers[p1];
        }
        numbers[p1]=povit;
        quiksort(numbers,start,p1-1);
        quiksort(numbers,p1+1,end);
    }

//冒泡排序
//平均时间复杂度:O(N^2)
//最坏情况复杂度:O(N^2)
//空间复杂度:O(1)
//稳定排序
void bubblesort(vector<int>& a)
{
    int n = a.size();
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n - 1 - i; j++)
        {
            if (a[j] > a[j+1])
                swap(a[j], a[j+1]);
        }
    }
}

//插入排序
//平均时间复杂度:O(N^2)
//最坏情况复杂度:O(N^2)
//最好情况复杂度:O(N)
//空间复杂度:O(1)
//最多需要n(n−1)/2次比较
//最少需要n−1次比较
//稳定排序
void insertsort(vector<int>& a)
{
    int n = a.size();
    for (int i = 1; i < n; i++)
    {
        int insert_num = a[i], j;
        for (j = i - 1; j >= 0; j--)
        {
            if (a[j] > insert_num)
                a[j + 1] = a[j];
            else
                break;
        }
        a[j + 1] = insert_num;
    }
}

//选择排序
//平均时间复杂度 O(n^2)
//最坏时间复杂度 O(n^2)
//最好时间复杂度 O(n^2)
//空间复杂度 O(1)
//我这个写法 是稳定排序
void select_sort(vector<int>& vt)
{
    for (int i = 0; i < vt.size() - 1; i ++)
    {
        int swap_pos = i;
        for (int j = i + 1; j < vt.size(); j++)
        {
            if (vt[swap_pos] > vt[j])
            {
                swap_pos = j;
            }
        }

        if (swap_pos != i)
        {
            swap(vt[swap_pos], vt[i]);
        }
    }
}

//希尔排序
//最坏情况复杂度:O(N^2)
//不稳定排序
void shellsort(vector<int>& a)
{
    int n = a.size();
    for (int increment = n / 2; increment > 0; increment /= 2)
    {
        for (int i = increment; i < n; i++)
        {
            int insert_num = a[i], j;
            for (j = i - increment; j >= 0; j -= increment)
            {
                if (a[j] > insert_num)
                    a[j + increment] = a[j];
                else
                    break;
            }
            a[j + increment] = insert_num;
        }
    }
}

//堆排序
//建堆的平均时间是:O(N)
//建堆的最坏情况是:O(NlogN)
//删除元素的时间是:O(logN)
//整个排序平均时间复杂度:O(N+NlogN)=O(NlogN)
//最坏情况复杂度:O(NlogN)
//不稳定排序
//建立一个大顶堆O(n),要求就是 把最大的元素 移动到堆顶 也就是a[0]
void make_heap(vector<int>& a, int size) //size的当前堆的大小,也就是数组的前size个数
{
    for (int i = size - 1; i > 0; i--)
    {
        if (i % 2 && a[i] > a[(i - 1) / 2])//奇数
            swap(a[i], a[(i - 1) / 2]);
        else if (i % 2 == 0 && a[i] > a[(i - 2) / 2])//偶数
            swap(a[i], a[(i - 2) / 2]);
    }
}
void heapsort(vector<int>& a)
{
    int n = a.size();
    while (n)
    {
        make_heap(a, n); //每次把新的最大元素移到堆顶,也就是a[0]
        n--;
        swap(a[0], a[n]); //然后把当前最大移动到后面来作为排好序的元素
    }
}

//归并排序
//平均时间复杂度:O(NlogN)
//稳定排序
vector<int> mergeHelper(vector<int> &a, int left, int right)
{
    if (left == right) return vector<int> (1, a[left]);
    int mid = (right - left) / 2 + left;
    vector<int> l = mergeHelper(a, left, mid);
    vector<int> r = mergeHelper(a, mid + 1, right);
    //merge
    vector<int> ret;
    int ll = 0, rr = 0;
    while (ll < l.size() && rr < r.size())
    {
        if (l[ll] <= r[rr])     ret.push_back(l[ll++]);
        else                    ret.push_back(r[rr++]);
    }
    while (ll < l.size()) ret.push_back(l[ll++]);
    while (rr < r.size()) ret.push_back(r[rr++]);
    return ret;
}

void mergesort(vector<int>& a)
{
    a = mergeHelper(a, 0, a.size() - 1);
}

(2)二维数组中的查找:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

bool Find(int target, vector<vector<int> > array)
    {
        int rows=array.size()-1,cols=array[0].size()-1;
        int i=0,j=cols;
        while(i<=rows&&j>=0){//行最大、列最小
            if(array[i][j]==target)
                return true;
            else if(array[i][j]<target)//小于他,向下移
                i++;
            else if(array[i][j]>target)//大于他,向左移
                j--;
        }
        return false;
    } 

(3)连续子数组的最大和

int FindGreatestSumOfSubArray(vector<int> array) {
        if(array.size()==0)
            return 0;
        int result=array[0],addvalue=array[0];
        for(int i=1;i<array.size();i++){
            if(addvalue>=0)
                addvalue+=array[i];
            else
                addvalue=array[i];
            if(addvalue>result)
                result=addvalue;
        }
        return result;
    }

(4)数组中只出现一次的数字

void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        if(data.size()<2)
            return;//直接return就行哦
        int temp=0;
        for(int i=0;i<data.size();++i)
            temp^=data[i];
        int indexof1=0;
        //(temp&1)==0中()必须加,&优先级更低
        while(((temp&1)==0)&&(indexof1<8*sizeof(int))){
            //sizeof(int)可以知道电脑的int占多少个字节,一个字节有8位
            temp=temp>>1;//一定要用temp=一下!不可以直接temp>>1
            ++indexof1;
        }
        *num1=0;*num2=0;
        for(int i=0;i<data.size();++i){
            if(IsBit1(data[i],indexof1))
                *num1^=data[i];
            else
                *num2^=data[i];
        }
    }
    bool IsBit1(int num,int index){
        num=num>>index;
        return (num&1);
    }

3.链表
(1)从尾到头打印链表

    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> Arraylist;
        if(head==nullptr)
            return Arraylist;
        stack<int> temp;
        ListNode* p=head;
        while(p!=nullptr){
            temp.push(p->val);
            p=p->next;
        }
        while(!temp.empty()){
            Arraylist.push_back(temp.top());
            temp.pop();
        }
        return Arraylist;
    }

(2)反转链表

ListNode* ReverseList(ListNode* pHead)
    {
        if(pHead==nullptr)
            return nullptr;
        ListNode* p=pHead;
        ListNode* pre=nullptr;
        while(p!=nullptr){
            ListNode* pnext=p->next;
            p->next=pre;
            pre=p;
            p=pnext;
        }
        return pre;
    }

(3)复杂链表的复制:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

    RandomListNode* Clone(RandomListNode* pHead)
    {
        if(pHead==nullptr)
            return nullptr;
        clonenodes(pHead);
        conectrandom(pHead);
        return reconect(pHead);
    }
    void clonenodes(RandomListNode* pHead){
        RandomListNode* p=pHead;
        while(p!=nullptr){
            RandomListNode* pClone=new RandomListNode(p->label);
            pClone->next=p->next;
            pClone->random=nullptr;
            p->next=pClone;
            p=pClone->next;
        }        
    }
    void conectrandom(RandomListNode* pHead){
        RandomListNode* p=pHead;
        RandomListNode* pClone=nullptr;
        while(p!=nullptr){
            pClone=p->next;
            if(p->random!=nullptr)
                pClone->random=p->random->next;
            p=pClone->next;
        }
    }
    RandomListNode* reconect(RandomListNode* pHead){
        if(pHead==nullptr)
            return nullptr;        
        RandomListNode* p=pHead;
        RandomListNode* pCloneHead=p->next;
        RandomListNode* pClone=pCloneHead;
        p->next=pClone->next;
        p=p->next;
        while(p!=nullptr){
            pClone->next=p->next;
            pClone=pClone->next;
            p->next=pClone->next;
            p=p->next;//一定要注意顺序,指针变化的先后
        }
        return pCloneHead;
    }

4.树
(1)重建二叉树

TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin)
    {
        if(pre.empty()||vin.empty())
            return nullptr;
        TreeNode* root=new TreeNode(pre[0]);//注意new的用法
        vector<int> leftpre,rightpre,leftvin,rightvin;
        int rootcount=0;
        while(vin[rootcount]!=pre[0]){
            rootcount++;
        }
        for(int i=0;i<vin.size();i++){
            if(i<=rootcount){
                if(i!=0)
                    leftpre.push_back(pre[i]);
                if(i!=rootcount)
                    leftvin.push_back(vin[i]);
            }
            if(i>rootcount){
                rightpre.push_back(pre[i]);
                rightvin.push_back(vin[i]);
            }
        }
        root->left=reConstructBinaryTree(leftpre,leftvin);
        root->right=reConstructBinaryTree(rightpre,rightvin);
        return root;
    }

(2)从上到下打印二叉树

vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> result;
        if(root==nullptr)
            return result;
        deque<TreeNode*> temp;
        temp.push_back(root);
        while(!temp.empty()){
            result.push_back(temp.front()->val);
            if(temp.front()->left!=nullptr)
                temp.push_back(temp.front()->left);
            if(temp.front()->right!=nullptr)
                temp.push_back(temp.front()->right);
            temp.pop_front();
        }
        return result;
    }

(3)三种递归遍历

//前序遍历
void preorder(TreeNode *root, vector<int> &path)
{
    if(root != NULL)
    {
        path.push_back(root->val);
        preorder(root->left, path);
        preorder(root->right, path);
    }
}

//中序遍历
void inorder(TreeNode *root, vector<int> &path)
{
    if(root != NULL)
    {
        inorder(root->left, path);
        path.push_back(root->val);
        inorder(root->right, path);
    }
}

//后续遍历
void postorder(TreeNode *root, vector<int> &path)
{
    if(root != NULL)
    {
        postorder(root->left, path);
        postorder(root->right, path);
        path.push_back(root->val);
    }
}

(4)按之字形顺序打印二叉树

vector<vector<int> > Print(TreeNode* pRoot) {
        if(pRoot==nullptr)
            return allresult;
        queue<TreeNode*> temp;
        temp.push(pRoot);
        int line=1,linecount=1,nextlinecount=0;
        while(!temp.empty()){
            while(linecount>0){
                result.push_back(temp.front()->val);
                if(temp.front()->left!=nullptr){
                    ++nextlinecount;
                    temp.push(temp.front()->left);
                }
                if(temp.front()->right!=nullptr){
                    ++nextlinecount;
                    temp.push(temp.front()->right);
                }
                temp.pop();
                --linecount;
            }
            allresult.push_back(result);
            result.clear();
            linecount=nextlinecount;
            nextlinecount=0;
        }
        int sizeofall=allresult.size();
        for(int i=0;i<sizeofall;++i){
            if(i&1==1){
                int p2=allresult[i].size()-1,p1=0,temp=0;
                while(p1<p2){
                    temp=allresult[i][p1];
                    allresult[i][p1]=allresult[i][p2];
                    allresult[i][p2]=temp;
                    ++p1;
                    --p2;
                }
            }
        }
        return allresult;
    }
private:
    vector<vector<int> > allresult;
    vector<int> result;

(5)二叉搜索树的第k个节点

    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        if(pRoot==nullptr||k<1)
            return nullptr;
        vector<TreeNode*> mid;
        midfind(pRoot,mid);
        if(k>mid.size())
            return nullptr;
        return mid[k-1];
    }
    void midfind(TreeNode* pRoot,vector<TreeNode*> &mid){
        if(pRoot!=nullptr){
            midfind(pRoot->left,mid);
            mid.push_back(pRoot);
            midfind(pRoot->right,mid);
        }
    }
};

(6)和为某一值的路径

public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber){
        if(root==nullptr)
            return allresult;
        result.push_back(root->val);
        if((root->val==expectNumber)&&(root->left==nullptr)&&(root->right==nullptr))
            allresult.push_back(result);
        FindPath(root->left,expectNumber-(root->val));
        FindPath(root->right,expectNumber-(root->val));
        result.pop_back();//这一步必须加!!
        return allresult;
    }
private:
    vector<vector<int> > allresult;
    vector<int> result;

(7)二叉搜索树与双向链表

TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(pRootOfTree==nullptr)
            return nullptr;
        TreeNode* pHead=pRootOfTree;
        while(pHead->left!=nullptr)
            pHead=pHead->left;
        FindLeftAndRight(pRootOfTree);
        return pHead;
    }
    void FindLeftAndRight(TreeNode* pRootOfTree){
        if(pRootOfTree->left!=nullptr){
            FindLeftAndRight(pRootOfTree->left);
            TreeNode* p=pRootOfTree->left;
            while(p->right!=nullptr)
                p=p->right;
            p->right=pRootOfTree;
            pRootOfTree->left=p;
        }
        if(pRootOfTree->right!=nullptr){
            TreeNode* p=pRootOfTree->right;
            FindLeftAndRight(pRootOfTree->right);//注意递归的位置,一定要在前面!
            while(p->left!=nullptr)
                p=p->left;
            p->left=pRootOfTree;
            pRootOfTree->right=p;
        }
    }

5.栈
(1)用两个栈来实现一个队列

public:
    void push(int num){
          stack1.push(num);
      }
    int pop(){
        int result;
        if(!stack2.empty()){
            result=stack2.top();
            stack2.pop();
        }
        else{
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
            }
            result=stack2.top();
            stack2.pop();
        }
        return result;
    }
private:
    stack<int> stack1;
    stack<int> stack2;

(2)包含min函数的栈

public:
    void push(int value){
        st.push(value);
        if(smin.empty()||value<smin.top())
            smin.push(value);
    }
    void pop() {
        if(st.top()==smin.top())
            smin.pop();
        st.pop();
    }
    int top() {
        return st.top();
    }
    int min() {
        return smin.top();
    }
    private:
    stack<int> st;//正常记录
    stack<int> smin;//小的压栈

(3)栈的压入、弹出序列
bool IsPopOrder(vector<int> pushV,vector<int> popV)
{
int pushcount=pushV.size(),popcount=popV.size();
if(pushcount!=popcount)
return false;
stack<int> temp;
int pi=0;
for(int i=0;i<popcount;++i)
{
while(temp.empty()||temp.top()!=popV[i])
{
temp.push(pushV[pi++]);
if(pi>pushcount)
return false;
}
temp.pop();
}
return true;
}
6.队列
(1)从上往下打印二叉树</int></int></int>

    vector<int> PrintFromTopToBottom(TreeNode* root) {
        vector<int> result;
        if(root==nullptr)
            return result;
        deque<TreeNode*> temp;
        temp.push_back(root);
        while(!temp.empty()){
            result.push_back(temp.front()->val);
            if(temp.front()->left!=nullptr)
                temp.push_back(temp.front()->left);
            if(temp.front()->right!=nullptr)
                temp.push_back(temp.front()->right);
            temp.pop_front();
        }
        return result;
    }

////////////////////会根据我的学习进展不断更新哦////////////////////////////欢迎一起努力的小伙伴们点赞收藏呀///////////////////////////////////////////////////
参考链接:https://blog.csdn.net/liqinzhe11/article/details/78743743
参考资料:剑指offer