剑指offer中数据结构与算法部分笔记

遍历:前中后序,宽度优先。

二叉树的特例:二叉搜索树、堆(最大堆和最小堆,用于找最值)、红黑树(c++ STL中的很多数据结果就是基于这实现的);

题7-重建二叉树:递归,设置四个位点;

class Linuxidc {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if(pre.size()!=vin.size()||vin.size()==0) return nullptr;
        return Construct(0,pre.size()-1,0,vin.size()-1,pre,vin);
    }
   
    TreeNode* Construct(int prestart,int preend,int vinstart,int vinend,const vector<int> &pre,const vector<int> &vin){
        if(prestart>preend) return nullptr;
        TreeNode* root=new TreeNode(pre[prestart]);
        for(int i=vinstart;i<=vinend;i++)
            if(pre[prestart]==vin[i]){
                root->left=Construct(prestart+1,prestart+i-vinstart,vinstart,i-1,pre,vin);
                root->right=Construct(prestart+i-vinstart+1,preend,i+1,vinend,pre,vin);
                break;
            }
        return root;
    }
};

题8-二叉树的下一个节点

class Linuxidc {
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        if(pNode==nullptr) return nullptr;
        if(pNode->right!=nullptr){
            pNode=pNode->right;
            while(pNode->left!=nullptr){
                pNode=pNode->left;
            }
            return pNode;
        }
        else{
            if(pNode->next==nullptr)
                return nullptr;
            else{
                if(pNode==pNode->next->left)
                    return pNode->next;
                else{
                    while(pNode->next!=nullptr){
                        if(pNode==pNode->next->left)
                            return pNode->next;
                        pNode=pNode->next;
                    }
                    return nullptr;
                }
            }
        }
    }
};

2.3.5 栈和队列

题9-两个栈实现队列:一个用于插入,一个用于删除,增加判空操作,每次插入/删除操作后只有一个栈是有数据的;

2.4 算法和数据结构

递归/循环,排序/查找,搜索路径(回溯法),最优解(动态规划),贪心,位运算(与、或、异或、左右移)

2.4.1 递归和循环

如果面试官没有要求,多采用递归;递归存在时间效率和调用栈溢出的问题;

题10-斐波那契数列:递归效率低,采用循环O(n),也可以用到数学公式用递归O(logn),青蛙跳和格子都是这个问题;

2.4.2 查找和排序

顺序查找、二分、哈希表查找、二叉排序树

交换使用swap函数,使用随机数配合递归来进行快排;

面试官的交流:要问排序的是什么数据、数据量,能用多少辅助空间?明确场景

题11-旋转数组的最小数字:O(n)到O(logn),使用二分,但是要有特殊处理,例如如果两个位点元素相等,则内部的应该进行顺序查找;

class Linuxidc {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.size()==0)  return 0;
        int low=0,high=rotateArray.size()-1,mid=(low+high)/2;
        if(rotateArray[low]<rotateArray[high]) return rotateArray[low];
        if(high<2) return rotateArray[high];
        while(low!=high-1){
            if(rotateArray[low]<rotateArray[high]) return rotateArray[low];
            if(rotateArray[low]==rotateArray[mid]&&rotateArray[mid]==rotateArray[high]){
                int min=rotateArray[low];
                for(int i=low+1;i<=high;i++)
                    if(min>rotateArray[i])
                        min=rotateArray[i];
                return min;
            }
            if(rotateArray[low]>rotateArray[mid]){
                //low=low+1;
                high=mid;
                mid=(low+high)/2;
            }
            if(rotateArray[high]<rotateArray[mid]){
                low=mid;
                mid=(low+high)/2;
            }
        }
        return rotateArray[low+1];
    }
};

2.4.3 回溯法

适合用递归实现,其实也可以用堆栈。

题13-机器人的运动规划:本来觉得两轮遍历就可以找到不可以到达的格子,后来发现是不对的,所以还是用了回溯去找

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ed8838b43729bff5724a47f0038ac737.html