剑指offer打卡 week1
13. 找出数组中重复的数字

https://www.acwing.com/problem/content/14/
思路:
由于数据范围在0-n-1,如果出现的数字都只有一次 我们可以构造出0,1,2,,,n-1的数组
所以我们每次循环吧数字交换到对应值的下标 操作完毕后查看是否满足nums[i]=i
如果不行说明是重复数字

class Solution {
public:
    int duplicateInArray(vector<int>& nums) {
        int n=nums.size();
        for(auto x:nums){
            if(x<0 || x>=n) return -1;
        }
        for(int i=0;i<n;i++){
            while(nums[i]!=nums[nums[i]]){
                swap(nums[i], nums[nums[i]]);
            }
            if(nums[i]!=i) return nums[i];
        }
        return -1;
    }
};
14. 不修改数组找出重复的数字

https://www.acwing.com/problem/content/15/

class Solution {
public:
    int duplicateInArray(vector<int>& nums) {
        set<int>s;
        for(int x:nums){
            int n=s.size();
            s.insert(x);
            if(s.size()==n){
                return x;
            }
        }
        return 0;
    }
};
15. 二维数组中的查找

https://www.acwing.com/problem/content/16/
思路 从左上角开始枚举 根据性质如果目标值大于左上角那么左上角点左边的列必不会出现答案
同理如果小于点下面的列就不是答案 每次判断都可以去掉一行或者一列来优化速度

class Solution {
public:
    bool searchArray(vector<vector<int>> array, int target) {
        int n=array.size();
        if(n==0) return false;
        int j=array[0].size();
        int x=0,y=j-1;
        int temp=array[x][y];//枚举左上角点
        while(x<n && y>=0){
            temp=array[x][y];//更新值
            if(temp>target){//此时数比目标值大 该点下面一列直接优化掉
                y--;
            }
            else if(temp<target){
                x++;
            }
            else {
                return true;
            }
        }
        //cout<<temp<<endl;
        return false;
    }
};
16. 替换空格

https://www.acwing.com/problem/content/17/

class Solution {
public:
    string replaceSpaces(string &str) {
        string s="";
        for(auto c:str){
            if(c!=' ') s+=c;
            else s+="%20";
        }
        return s;
    }
};
17. 从尾到头打印链表

https://www.acwing.com/problem/content/18/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> printListReversingly(ListNode* head) {
        vector<int>ans;
        if(head==NULL) return ans;
        else ans.push_back(head->val);
        while(head->next!=NULL){
            head=head->next;
            ans.push_back(head->val);
        }
        int n=ans.size();
        vector<int>ans2(n);
        for(int i=0;i<n;i++){
            ans2[i]=ans[n-i-1];
        }
        return ans2;
    }
};
18. 重建二叉树

https://www.acwing.com/problem/content/23/
思路:
剑指offer打卡 week1_i++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    unordered_map<int,int>map;
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n=preorder.size();
        for(int i=0;i<n;i++){
            map[inorder[i]]=i;//记录数值对应在中序遍历的位置
        }
        return dfs(preorder,inorder,0,n-1,0,n-1);
    }
    TreeNode* dfs(vector<int>& pre,vector<int>& ino,int pl,int pr,int il,int ir){
        if(pl>pr)return NULL;
        auto root=new TreeNode(pre[pl]);
        int k=map[root->val]-il;
        root->left=dfs(pre,ino,pl+1,pl+k,il,il+k-1);//这里就根据测试数据慢慢推
        //pl pr 左子树在前序的区间
        //il ir 右子树在中序的区间
        //下面同理
        root->right=dfs(pre,ino,pl+k+1,pr,il+k+1,ir);
        return root;
    }
};
19. 二叉树的下一个节点

https://www.acwing.com/problem/content/31/
思路:
剑指offer打卡 week1_数组_02

class Solution {
public:
    TreeNode* inorderSuccessor(TreeNode* p) {
        if (p->right) {
            p = p->right;
            while (p->left) p = p->left;
            return p;
        }

        while (p->father && p == p->father->right) p = p->father;
        return p->father;
    }
};
20. 用两个栈实现队列

https://www.acwing.com/problem/content/36/

class MyQueue {
public:
    stack<int>s1,s2;
    /** Initialize your data structure here. */
    MyQueue() {
        
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
        s1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        int ans;
        while(s1.size()){
            int temp=s1.top();
            if(s1.size()>1)
            s2.push(temp);
            else ans=s1.top();
            s1.pop();
        }
        while(s2.size()){
                int temp=s2.top();
                s1.push(temp);
                s2.pop();
        }
        return ans;
    }
    
    /** Get the front element. */
    int peek() {
        while(s1.size()>1){
            int temp=s1.top();
            s2.push(temp);
            s1.pop();
        }
        int temp=s1.top();
        while(s2.size()){
            s1.push(s2.top());
            s2.pop();
        }
        return temp;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return s1.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * bool param_4 = obj.empty();
 */
21. 斐波那契数列

https://www.acwing.com/problem/content/19/

class Solution {
public:
    int a[100];
    int Fibonacci(int n) {
        if(n==0) return 0;
        if(n<=2) return 1;
        if(a[n]>0) return a[n];
        return a[n]=Fibonacci(n-1)+Fibonacci(n-2);
    }
};