剑指offer刷题笔记(1)

明年就要春招找实习了,今天考研最后一天,有的人考研快结束了,我的考研生活才刚刚开始,奋战一百天,BAT搬砖不是梦。


39.二叉树深度            知识点:二叉树遍历(后序遍历),其实前序遍历也是可以的
class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        if (pRoot == NULL)
            return 0;
        int left = TreeDepth(pRoot->left);
        int right = TreeDepth(pRoot->right);
        return left>right?left+1:right+1;
    }
};
47.不用加减乘除做加法    知识点:位运算            其实学过数电的话其实懂加法电路的设计这道题就容易懂了
class Solution {
public:
    int Add(int num1, int num2)
    {
        int sum = 0;
        int carry = 0;
        do{
            sum = num1^num2;
            carry = (num1&num2)<<1;
            num1 = sum;
            num2 = carry;
        }while(carry != 0);

            return sum;

    }
};
19.二叉树的镜像      知识点:二叉树的遍历  (前序,后序都可以的, 中序不可以)
class Solution {
public:
    void Mirror(TreeNode *pRoot) {
        if (pRoot !=NULL)
            {
            TreeNode * temp;
            temp = pRoot->left;
            pRoot->left = pRoot->right;
            pRoot->right = temp;

            Mirror(pRoot->left);
            Mirror(pRoot->right);
        }
    }
};
9.扩展 变态跳台阶  知识点:分治法,使用递归做
class Solution {
public:
    int jumpFloorII(int number) {
        if (number == 1)
            return 1;
        if (number == 2)
            return 2;
        else
            {
            int sum  = 0;

            while (--number)
                sum  += jumpFloorII(number);

            return sum + 1;

        }
    }
};
52.构建乘积数组       知识点:找规律     本身不难
class Solution {
public:
    vector multiply(const vector& A) {
    int length = A.size();
    long long int a[length];
    long long int b[length];
    vector B;
        a[0] = 1;
        b[length-1] = 1;

        for (int j = length - 2;j>=0; j--)
            {
                b[j] = b[j+1] * A[j+1];
            }

        B.push_back(b[0]);

         for (int i = 1; i
            {
                 a[i] = a[i-1]*A[i-1];
                 B.push_back(a[i]*b[i]);
            }

        return     B;
    }
};
7.用两个栈实现队列     知识点:栈和队列的进出规律  
class Solution
{
public:
    void push(int node) {
        if (stack1.empty())
            {
            while(stack2.size()>0)
                {
                int data = stack2.top();
                stack2.pop();
                stack1.push(data);
            }
        }
        stack1.push(node);
    }

    int pop() {
        if (stack2.empty())
            {
            while( stack1.size()> 0)
                {
                int data = stack1.top();
                stack1.pop();
                stack2.push(data);
            }
        }
       int top =  stack2.top();
        stack2.pop();
        return top;
    }

private:
    stack stack1;
    stack stack2;
};
10.二进制中1的个数  知识点:位运算         与运算第一次没做出来,囧
class Solution {
public:
     int  NumberOf1(int n) {
             int count = 0;
              int  indexBit = 1;
              int time = 32;
         while(time--)
             {

                 if(indexBit&n)
                    count++;

                 indexBit = indexBit<<1;
            }
         return count;
     }
};

int Count1(unsigned int v)
{
    int num = 0;

    while(v)
    {
         if(v % 2 == 1)
         {
              num++; 
         }
         v = v/2;
    }

    return num;
}

int Count3(unsigned int v)
{
    int num = 0;

    while(v)
    {
         v &= (v-1);
         num++;
    }
    return num;
}
46.求1+2+3+……+n  刚开始把两个类写一起了,结果不行,回去的看一下类内函数与构造的关系
class helper {
public:

    helper(){
        sum += (++n);
    }

    static void reset(){
        n = 0;
        sum = 0;
    }

    static unsigned int getSum(){
        return sum;
    }

private:
    static unsigned int n;
    static unsigned int sum;
};

unsigned int helper::n = 0;
unsigned int helper::sum = 0;


class Solution {
public:
    int Sum_Solution(int n) {
        helper::reset();

        helper *s = new helper[n];

        int res = helper::getSum();

        delete[]s;

        return res;
    }
};

39.平衡二叉树深度     知识点:二叉树遍历变种
class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {
        if (pRoot==NULL)
            return true;
        int left;
        int right;

        bool flagl;
        bool flagr;
        TreeDepth(pRoot->left, left, flagl);
        TreeDepth(pRoot->right, right, flagr);
        if (left-right>= -1 && left-right<=1)
              return flagl&&flagr;
        else
            return false;
    }

  void TreeDepth(TreeNode* pRoot, int& depth, bool &flag)
    {
        if (pRoot == NULL)
            {
            depth = 0;
            flag = true;
            }
       else{
       int left;
       int right;
       bool flagl;
       bool flagr;
       TreeDepth(pRoot->left,left,flagl);
       TreeDepth(pRoot->right,right,flagr);
       depth = (left>right?left+1:right+1);
        if (left-right>= -1 && left-right<=1)
             flag = flagl&&flagr;
        else
            flag =  false;
    }   
  }

};
9.跳台阶, 知识点:斐波那契数列,循环和递归
矩形覆盖  知识点:斐波那契数列, 循环和递归    两种方法都要掌握,难度easy
class Solution {
public:
    int jumpFloor(int number) {
        if (number == 1)
            return 1;
        else if (number == 2)
            return 2;
        else
            return jumpFloor(number-1) + jumpFloor(number-2);
    }
};

class Solution {
public:
    int rectCover(int number) {
        if (number == 1)
            return 1;
        else if(number==2)
            return 2;
            int first = 1;
            int second = 2;
            int third = 0;
        for(int i = 3;i<=number;i++)
            {
             third = first + second;
            first = second;
            second = third;
        }
        return third;
    }
};
37.两个链表的第一个公共节点     知识点:链表的遍历    还有链表有环的问题, 这类题一般设置两个访问点,要不然起始位置不一样,要不然设置遍历速度不一样。
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if (pHead1 == NULL || pHead2 == NULL)
            return NULL;
        ListNode* first = pHead1;
        ListNode* second = pHead2;
        int size1 = 0;
        int size2 = 0;
        while(first!=NULL)
            {
            size1++;
            first = first->next;
        }

        while(second!=NULL)
            {
            size2++;
            second = second->next;
        }

        if (size1>size2)
            {
            int n = size1 - size2;
            first = pHead1;

            while(n--)
                {
                first = first->next;
            }
            second = pHead2;
        }

        else{
            int n = size2 - size1;
            second = pHead2;

            while(n--)
                {
                second = second->next;
            }
            first = pHead1;
        }

        for(;first!= second;first->next, second->next);

        return second;


    }
};
31.连续子数组的最大和    知识点:尺取法        刚开始还绕了好久,在array[i]上大于0才比较,没考虑数组本身就可能都是负数的可能性,我觉得比书上的要清晰
class Solution {
public:
    int FindGreatestSumOfSubArray(vector array) {
    int max = array[0];
    int sum = array[0];
    for (int i = 1; i
        {
            if (sum < 0)
                sum = 0;
            sum += array[i];         
             max = sum>max?sum:max;
    }

    return max;
    }
};
59.对称的二叉树  知识点:二叉树遍历变种,需要多加一个flag标志位,后序遍历来自底层的判断flag往根节点传送,没看书上的解法做得,确实还是可以再优化一步的
class Solution {
public:
    bool isSymmetrical(TreeNode* pRoot)
    {
        if (pRoot==NULL)
            return true;
        TreeNode* left = pRoot->left;
        TreeNode* right = pRoot->right;
        return isEqual( left,  right);

    }

    bool isEqual(TreeNode* left, TreeNode* right){
        if (left==NULL && right == NULL)
            return true;
        else if (left !=NULL && right!=NULL)
        {
            bool flag1 = isEqual(left->right, right->left);
            bool flag2 = isEqual(left->left, right->right);
            if (left->val  == right->val )
                return flag1&&flag2;
            else
                return false;
        }
        else
            return false;
    }
};
41.和为s            前后夹击
class Solution {
public:
    vector FindNumbersWithSum(vector array,int sum) {
        int length = array.size();
        int l = 0;
        int r = length -1;
       vector index(2, -1);
        long long int min  = 0xEFFFF;
        while(l
            if (array[l] + array [r] == sum)
             {
                  if(array[l]*array[r]< min)
                   {
                  index[0] = array[l];
                  index[1] = array[r];
                  min = array[l]*array[r];
                  }
                l++;
                r--;
             }

            if (array[l] + array [r] < sum)
            {
                l++;
            }
            if (array[l] + array [r] > sum)
            {
                r--;
            }


            }

        if (index[1] == -1)
            index.clear();
        return index;
        }

};
51.数组中重复的数字         知识点:hash                     这里利用了原数组的内存空间,省去了另外开辟空间,想法很巧妙
 class Solution {
public:
    // Parameters:
    //        numbers:     an array of integers
    //        length:      the length of array numbers
    //        duplication: (Output) the duplicated number in the array number
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    bool duplicate(int numbers[], int length, int* duplication) {
        for (int i = 0; i
            {
            while(numbers[i]!= i)
            {
                if (numbers[numbers[i]] == numbers[i])
                    {
                        *duplication = numbers[i];
                        return true;
                    }
                int temp = numbers[i];
                numbers[i] = numbers[temp];
                numbers[temp] = temp;           
            }           
            }
            return false;

    }
};

你可能感兴趣的:(算法)