剑指offer刷题(2)

1.合并两个排序的链表:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

思路:不知道用循环行不行,自己编译的不能通过。确实递归的方法更好一些:

困惑:定义一个链表的变量不确定是声明一下,还是申请一下地址。

自己的程序没有ac:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        ListNode* res=NULL;
        ListNode* head=res;
        //ListNode* res=new ListNode*(pHead1);
      //  ListNode head=res(-1);
        //if(pHead1==NULL&&pHead2==NULL)
         //   return NULL;
        if(pHead1==NULL)
            return pHead2;
        if(pHead2==NULL)
            return pHead1;
        while(pHead1->next!=NULL&&pHead2->next!=NULL)
        {
            if(pHead1->val<=pHead2->val)
        {
            res->next=pHead1;
            res=res->next;
            pHead1=pHead1->next;
        }
            else{
                res->next=pHead2;
            res=res->next;
            pHead2=pHead2->next;
            }
        }
        return head;    
    }
};

用递归的方法做:

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1==NULL)
            return pHead2;
        if(pHead2==NULL)
            return pHead1;
        ListNode* res=NULL;
        if(pHead1->val<=pHead2->val)
        {
            res=pHead1;
             res->next=Merge(pHead1->next,pHead2);
            }
    else
    {
        res=pHead2;
        res->next=Merge(pHead1,pHead2->next);
    }
    return res;
    }
};

2.二进制中1的个数:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路:可以整数右移,但是有一个人正数和负数的问题。若是负数最高位是1.也可以1左移。(位与是&,与是&&)循环左移1,再与整数位与。(困惑:循环截至条件是1的左移的值,但是1是不断变大的,何时截至)思路3也可以整数减1之后再与原整数位与,然后原整数变为位与的结果值,循环。

思路2的程序:

class Solution {
public:
     int  NumberOf1(int n) {
        
            unsigned int b=1;
             int count=0;
             while(b) //为什么是b就行
             {
                 if(n&b)  //这里没有区分&& 和&
                     count++;
                 b=b<<1;
             }
         
         return count;
     }
};

3.顺时针打印矩阵:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        vector<int> res;
        int row=matrix.size();
        int col=matrix[0].size();
        if(row==0||col==0)
            return res;
        int left=0;
        int right=col-1;
        int top=0;
        int dtn=row-1;
        while(left<right&&top<dtn)
        {
            int i,j;
            for(int i=top,j=left;j<right;j++)
                 res.push_back(matrix[i][j]);
            if(top<dtn)
            {
                for(int j=right,i=top;i<dtn;i++)
                    res.push_back(matrix[i][j]);
            }
            if(left<right&&top<dtn)
            {
                for(int i=dtn,j=right;j>left;j--)
                    res.push_back(matrix[i][j]);
            }
            if(top<dtn&&left<right)
            {
                for(int i=dtn,j=left;i>top;i--)
                    res.push_back(matrix[i][j]);
            }
            left++,right--;
            top++,dtn--;
         
        }
        return res;

    }
};

4.按之字形顺序打印二叉树:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

思路:我原先以为用栈和队都是可以的,队是先进先出,栈是后进先出,。但是用队的话,它的下一行就无法实现之字形打印,因为下一行完全是反方向的,不但结点是反方向而且左右子树也要是反方向,队不满足左右左右结点。而栈就符合这个性质,所以只能用栈。

<原先错误的程序用了队,编译不过>

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    queue<TreeNode*> q1,q2;
    vector<vector<int>> res;
  // vector<int> tmp;
   // int flag=0;
    vector<vector<int> > Print(TreeNode* pRoot) {
        if(pRoot==NULL)
            return res;
        TreeNode* fr;
        //int flag=0;       
        q1.push(pRoot);
     //   tmp.push_back(pRoot->val);
   //     res.push_back(tmp);
   //     tmp.clear();
            while(q1.size()!=0||q2.size()!=0)
            {
                if(!q1.empty())
                {
                    vector<int> tmp;              
                while(!q1.empty())
            {
                
                    
                fr=q1.front();
                tmp.push_back(fr->val);
                q1.pop();  
                if(fr->right!=NULL)
                { q2.push(fr->right);
                    //tmp.push_back(fr->right->val);
                }
                if(fr->left!=NULL)
                {q2.push(fr->left);
                    //tmp.push_back(fr->left->val);
                }
                             
                }
              res.push_back(tmp);
              tmp.clear();
                }
             if(!q2.empty())
             {vector<int> tmp;
                while(!q2.empty())
                {
                    
                   fr=q2.front();
                    q2.pop();
                    if(fr->left!=NULL)
                { q1.push(fr->left);
                    //tmp.push_back(fr->left->val);
                }
                if(fr->right!=NULL)
                {q1.push(fr->right);
                   // tmp.push_back(fr->right->val);
                }     
              res.push_back(tmp);
              tmp.clear();
                }            
             }
          
         }
            
        
        return res;
    }
};

用栈的程序(依然未通过,怀疑是tmp定义的位置不对):

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    
  // vector<int> tmp;
   // int flag=0;
    vector<vector<int> > Print(TreeNode* pRoot) {
        stack<TreeNode*> q1,q2;
        vector<vector<int>> res;
        if(pRoot==NULL)
            return res;
        TreeNode* fr;
        //int flag=0;       
        q1.push(pRoot);
     //   tmp.push_back(pRoot->val);
   //     res.push_back(tmp);
   //     tmp.clear();
            while(q1.size()!=0||q2.size()!=0)
            {
                if(!q1.empty())
                {
                    vector<int> tmp;              
                while(!q1.empty())
            {                                   
                fr=q1.top();
                tmp.push_back(fr->val);
                q1.pop();  
                if(fr->right!=NULL)
                { q2.push(fr->right);
                    //tmp.push_back(fr->right->val);
                }
                if(fr->left!=NULL)
                {q2.push(fr->left);
                    //tmp.push_back(fr->left->val);
                }
                             
                }
                
                   
              res.push_back(tmp);
              tmp.clear();
                }
                
             if(!q2.empty())
             {vector<int> tmp;
                while(!q2.empty())
                {
                    
                   fr=q2.top();
                   tmp.push_back(fr->val);
                   q2.pop();
                   if(fr->left!=NULL)
                { q1.push(fr->left);
                    //tmp.push_back(fr->left->val);
                }
                if(fr->right!=NULL)
                {q1.push(fr->right);
                   // tmp.push_back(fr->right->val);
                }   
                
              res.push_back(tmp);
             tmp.clear();
                }
                            
             }
          
         }
            
        
        return res;
    }
};

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

思路:从左下往右上找,或从右上往左下找。

【错误的程序】

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        if(array.size()!=0)
        {
        int i,j;
        int lsize=array[0].size()-1;
        int hsize=array.size()-1;  //刚知道求行数的方法
        
        i=0;
        j=lsize;
        while(i>=0&&i<=hsize&&j>=0&&j<=lsize)
        {
            if(array[i][j]==target)
            {
                return true;
                break;}
              
            if(array[i][j]<target)
                i++;
            else if(array[i][j]>target)
                j--;
            
        }
            return false;
        
        }
    }
};


6.数组中超过一半的数:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

思路:用的土方法,先排序,再积累相同的。剑指offer书是用快速排序,但是也需要确定个数是否超过一半。

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.empty())
            return 0;
        int len=numbers.size();
        int len1=len>>1;
        sort(numbers.begin(),numbers.end());
        int num=0;
        int temp=0;
        for(int i=0;i<len;i++)
        {
            if(numbers[i]==temp)
                num+=1;
            else
            {
                num=0;
                temp=numbers[i];
                }
            if(num>=len1)
            {
                return numbers[i];
                break;
            }
           
        }
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/weixin_35837473/article/details/83217022