《剑指 Offer(第 2 版)》系列刷题

Posted 陆嵩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指 Offer(第 2 版)》系列刷题相关的知识,希望对你有一定的参考价值。

剑指offer刷题

文章目录

03 [数组中重复的数字]

class Solution 
public:
    int findRepeatNumber(vector<int>& nums) 
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++)
        
            if(nums[i+1]==nums[i])
            
                //cout<<nums[i]<<endl;
                //break;
                return nums[i];

            
                
        
        return 0;


    
;

04 [二维数组中的查找]

class Solution 
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) 
        if(matrix.empty()) return false;
        if(matrix[0].empty()) return false;
        int m = matrix.size();
        int n = matrix[0].size();
        for(int i=0;i<m;i++)
        
            if(matrix[i][0]<=target&&matrix[i][n-1]>=target)
            
                for(int j=0;j<n;j++)
                
                    if(matrix[i][j]==target)
                    return true;

                

            


        
        return false;



    
;  

05 [替换空格]

class Solution 
public:
    string replaceSpace(string s) 
        vector<int> place;

        for(int i=0;i<s.size();i++)
        
            if(s[i] == ' ')
            
                place.push_back(i);
                
            
        
        for(auto it=place.rbegin();it!=place.rend();it++)
        
            int i = *it;
            s[i] = '%';
            s.insert(i+1,"20");

        
        return s;

    
;                          

insert 是在 pos 处前插。

06 [从尾到头打印链表]

/**
 * Definition for singly-linked list.
 * struct ListNode 
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) 
 * ;
 */
class Solution 
public:
    vector<int> reversePrint(ListNode* head) 
        int count = 0;
        auto tmp = head;
        while(tmp!=NULL)
        
            count++;
            tmp = tmp->next;
        
        vector<int> result(count,0);
        tmp = head;
        while(tmp!=NULL)
        
            result[--count] = tmp->val;
            tmp = tmp->next;
        
        return result;

    
;

07 [重建二叉树]

/**
 * Definition for a binary tree node.
 * struct TreeNode 
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) 
 * ;
 */


 TreeNode* recursion(vector<int>& preorder,int p1,int p2,vector<int>& inorder,int q1,int q2)
 
     if(p1>p2||q1>q2) return NULL;
     TreeNode* newNode = new TreeNode(preorder[p1]);
     int leftTreeLen;
     for(int i=q1;i<=q2;i++)
     
         if(preorder[p1] == inorder[i])
         
             leftTreeLen = i-q1;
             break;

         
     
     //递归左子树
     TreeNode* leftNode = recursion(preorder, p1+1, p1+leftTreeLen,inorder, q1, q1+leftTreeLen-1);
     newNode->left = leftNode;
     //递归右子树
     TreeNode* rightNode = recursion(preorder, p1+leftTreeLen+1, p2,inorder, q1+leftTreeLen+1, q2);
     newNode->right = rightNode;
     return newNode;
 
class Solution 
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
         TreeNode* root;
         root = recursion(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
         return root;

    
;                                           

想把树串起来的题,递归时可以把 root 节点返回到上一层。

09 [用两个栈实现队列]

class CQueue 
public:
    stack<int> s1,s2;
    CQueue() 
        
    
    
    void appendTail(int value) 
        s1.push(value);

    
    
    int deleteHead() 
        if(s2.empty())
        
            if(s1.empty()) return -1;
            while(!s1.empty())
            
                s2.push(s1.top());
                s1.pop();
            
        
        int tmp = s2.top();
        s2.pop();
        return tmp;
    
;

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue* obj = new CQueue();
 * obj->appendTail(value);
 * int param_2 = obj->deleteHead();
 */

10-I [斐波那契数列]

class Solution 
public:
    int fib(int n) 
        int f0 = 0;
        int f1 = 1;
        int tmp;
        if(n==0) return f0;    
        for(int i=0;i<n-1;i++)
        
            //cout<<f1<<endl;
            tmp = (f0+f1)%1000000007;
            f0 = f1;
            f1 = tmp;
            
        
        //cout<<f1<<endl;
        return f1;
    
;                      

主要审题要认真,取模要注意。

10-II [青蛙跳台阶问题]

class Solution 
public:
    int numWays(int n) 
        if(n<=1) return 1;
        int a1 = 1;
        int a2 = 2;
        int a;
        for(int i=0;i<n-2;i++)
        
            a = (a1+a2)%1000000007;
            a1=a2;
            a2 = a;
        
        return a2;

    
;                  

11 [旋转数组的最小数字]

class Solution 
public:
    int minArray(vector<int>& numbers) 
        int size =  numbers.size();
        for(int i=0;i<size-1;i++)
        
            if(numbers[i+1]<numbers[i])
            
                return numbers[i+1];
            

        
        return numbers[0];
    
;               

12 [矩阵中的路径]

class Solution 
    int iMax,jMax;
    int size;
    vector<vector<bool>> b;
    vector<vector<char>> board1;
    string word1;
public:
    bool recursion(int i,int j,int pos)
    
        //cout<<"i=="<<i<<"j="<<j<<"pos="<<pos<<"size="<<size<<endl;
        if(pos==size-1) return true;
        if(i+1<iMax&&b[i+1][j]&&board1[i+1][j]==word1[pos+1])
        
            b[i+1][j] = false;
            if(recursion(i+1,j,pos+1)) return true;
            b[i+1][j] = true;
        
        if(j+1<jMax&&b[i][j+1]&&board1[i][j+1]==word1[pos+1])
        
            //cout<<"position="<<pos<<endl;
            b[i][j+1] = false;
            if(recursion(i,j+1,pos+1)) return true;
            b[i][j+1] = true;
        
        if(i-1>-1&&b[i-1][j]&&board1[i-1][j]==word1[pos+1])
        
            b[i-1][j] = false;
            if(recursion(i-1,j,pos+1)) return true;
            b[i-1][j] = true;
        
        if(j-1>-1&&b[i][j-1]&&board1[i][j-1]==word1[pos+1])
        
            //cout<<"hahaha"<<endl;
            //cout<<"ij_1b"<<i<<j-1<<" "<<b[i][j-1]<<endl;
            b[i][j-1] = false;
            if(recursion(i,j-1,pos+1)) return true;
            b[i][j-1] = true;
        
        return false;
    
    bool exist(vector<vector<char>>& board, string word) 
        //cout<<"to here"<<endl;
        iMax = board.size();
        jMax = board[0].size();
        //cout<<"iMax="<<iMax<<"jMax"<<jMax<<endl;
        vector<bool> tmp(jMax,true);
        //cout<<"to here"<<endl;
        b.resize(iMax,tmp);
        board1 = board;
        word1 = word;
        size = word.size();
        for(int i=0;i<iMax;i++)
        
            for(int j=0;j<jMax;j++)
            
                if(board[i][j]!=word[0]) continue;
                b[i][j] = false;
                //cout<<"ij="<<i<<" "<<j<<endl;
                if(recursion(i,j,0)) return true;
                b[i][j] = true;
            
        
        return false;
    
; 

13 [机器人的运动范围]

class Solution 
    int  result;
    int digitSum(int i,int j)
    
        int sum = 0;
        while(1)
         
            sum = sum+i%10;
            if(i/10==0) break;
            i = i/10;    
        
        while(1)
         
            sum = sum+j%10;
            if(j/10==0) break;
            j = j/10;    
        
        return sum;

    
    int recursion(int i,int j,int m,int n,vector<vector<bool>> &vis)
    
        if(i+1<m&&j<n&&vis[i+1][j])
        
            result++;
            vis[i+1][j] = false;
            recursion(i+1,j,m,n,vis);
        
        if(i<m&&j+1<n&&vis[i][j+1])
        
            vis[i][j+1] = false;
            result++;
            recursion(i,j+1,m,n,vis);
        
        return 0; 

    
public:
    int movingCount(int m, int n, int k) 
        vector<vector<bool>> vis(m,vector<bool>(n,true));
        result = 1;
        for(int i=0;i<m;i++)
        
            for(int j=0;j<n;j++)
            
                if(digitSum(i,j)>k)
                
                    vis[i][j] = false;
                
            
        
        recursion(0,0,m,n,vis);
        return result;




        


    
;                                                                   

记住要找一个矩阵记录已经走过的地方。

14-I [剪绳子]

class Solution 
public:
    int cuttingRope(int n) 
        vector<int> dp(n+1);
        dp[2] = 1; 
        for(int i=3;i<n+1;i++)
        
            for(int j=1;j<=i-j;j++)
            
                //cout<<i<<endl;
                //cout<<j<<endl;
                dp[i] = max(dp[i],j*dp[i-j]);
                dp[i] = max(dp[i],j*(i-j));

            
            
        
        return dp[n];
    
;

学会用简单列举法来找动态规划的规律。

14-II [剪绳子 II]

class Solution 
    int mypow(int a,int n,int base)
    
        long int tmp = base;
        for(int i=0;i<n;i++)
        
            tmp = tmp*a;
            tmp = tmp%1000000007;
        
        return tmp;
    
public:
    int cuttingRope(int n) 
        if(n==2) return 1;
        if(n==3) return 2;
        int num = ceil(n/3.0);
        int rem = n%3;
        int r;
        if(rem==0)
        
            r = (mypow(3,num,1));

        
        else if(rem==1)
        
            r = mypow(3,num-2,4);

        
        else
            r = mypow(3,num-1,2);

        
        return r;

    
;

割绳子的题目总是尽可能割成长度为 3 的比较好。不得已的情况下,尽可能地割成等长的。
INT_MAX = 2147483647(十位数)
INT_MIN = -2147483648(十位数)
所以:int -2147483648~2147483647
int 不够放的 long int 一般够了。

15 [二进制中 1 的个数]

class Solution 
public:
    int hammingWeight(uint32_t n) 
        int count = 0剑指 Offer(第 2 版)刷题 | 05. 替换空格

剑指 Offer(第 2 版)刷题 | 04. 二维数组中的查找

剑指 Offer(第 2 版)刷题 | 03. 数组中重复的数字

剑指offer系列——剑指 Offer 22. 链表中倒数第k个节点(C语言)

剑指offer第二版和专项突击版有啥区别

牛客剑指offer刷题记录