其他问题

  1. 不使用加号的加法

    LeetCode 371

    输入:a=1,b=2

    输出:3

    /*
    思路:不使用加号的加法一般有三步:1)计算a^b,这个计算出来的是不考虑进位的值;2)a&b这个计算出来的是考虑进位的值;3)将考虑进位的值向左移动1位,作为b,将不考虑进位的值作为a,递归调用此函数。
    */
    class Solution {
    public:
       int getSum(int a, int b) {
           if(b == 0)
               return a;
    
           int axor = a ^ b;
           int axand = a & b;
    
           int res = getSum(axor, axand<<1);
           return res;
       }
    };
  2. 不用除号的除法

    LeetCode 29

    输入:dividend = 10, divisor = 3

    输出:3

    输入:dividend = 7, divisor = -3

    输出:-2

    /*
    思路:题目要求不使用乘数号,其实除法相当于给被除数减除数,直到被除数小于等于0。因此,我们可以先对除数进行乘2操作,找到最小的大于被除数的值,这时进行了几次操作乘2操作,就是商的值,最后再对符号进行处理即可。
    */
    class Solution {
    public:
       int divide(int dividend, int divisor) {
    
           int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;
           long long int m = abs((long long) dividend);
           long long int n = abs((long long) divisor);
    
    
           long long res = 0;
    
           while(m >= n)
           {
               long long temp = n;
               long long i = 1;
               while(temp << 1 < m)
               {
                   temp = temp<<1;
                   i = i<<1;
               }
               m -= temp;
               res += i;
           }
    
           if(sign < 0)
               res = -res;
           return res > INT_MAX ? INT_MAX: res;
       }
    };
  3. 计算数组中其余元素乘积

    LeetCode 238

    给定一个数组,输出另外一个数组,输出数组每一位代表输入数组除了这一位以外,其余位的乘积。

    输入:[1,2,3,4]

    输出:[24,12,8,6]

    class Solution {
    public:
       vector<int> productExceptSelf(vector<int>& nums) {
           int len = nums.size();
    
           vector<int> fromBegin(len);
           vector<int> fromLast(len);
           vector<int> res(len);
           fromBegin[0] = 1;
           fromLast[0] = 1;
    
           for(int i = 1; i < len; ++i)
           {
               fromBegin[i] =fromBegin[i-1] * nums[i - 1];
               fromLast[i] = fromLast[i-1] * nums[len - i];
           }
    
           for(int i = 0; i < len; ++i)
               res[i] = fromBegin[i] * fromLast[len - i - 1];
           return res;
       }
    };
  4. 最大二叉树深度

    LeetCode 104

    最大二叉树深度实际上就是二叉树的深度。

    输入:[3,9,20,null,null,15,7]

       3
      / \
     9  20
       /  \
      15   7

    输出:3

    方法一:递归法

    /*
    思路:采用递归的思路,进行层序遍历,即可求出最大深度。
    */
    /**
    * Definition for binary tree
    * struct TreeNode {
    *     int val;
    *     TreeNode *left;
    *     TreeNode *right;
    *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    * };
    */
    class Solution {
    public:
       int maxDepth(TreeNode *root) {
           if(root == NULL)
               return 0;
           int ldepth = maxDepth(root->left) + 1;
           int rdepth = maxDepth(root->right) + 1;
           return max(ldepth,rdepth);
       }
    };

    方法二:引入queue

    /*
    思路:常用的层序遍历方法是采用队列,将每一层元素依次入队列,然后进行深度的计算
    */
    /**
    * 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:
       /*int maxDepth(TreeNode* root) {
           if(root == nullptr)
               return 0;
           int left = maxDepth(root->left) + 1;
           int right = maxDepth(root->right) + 1;
    
           return max(left,right);
    
       }*/
    
       int maxDepth(TreeNode* root)
       {
           if(root == nullptr)
               return 0;
           queue<TreeNode*> q;
           int count = 0;
           int next = 1;
           q.push(root);
           int depth = 0;
    
           while(q.size() != 0)
           {
               TreeNode* current = q.front();
               q.pop();
               count++;
               if(current->left != NULL)
                   q.push(current->left);
               if(current->right != NULL)
                   q.push(current->right);
    
               if(count == next)
               {
                   count = 0;
                   depth++;
                   next = q.size();
               }
           }
           return depth;
    
       }
    };
  5. 最小二叉树深度

    LeetCode 111

    因为深度是必须到叶子节点的距离,因此使用深度遍历时,不能单纯的比较左右子树的递归结果返回较小值,因为对于有单个孩子为空的节点,为空的孩子会返回0,但是这个节点并非叶子节点,所以返回结果是错误的。因此,当发现当前处理的节点有单个孩子是空时,返回一个极大值INT_MAX,防止其干扰结果。

    /**
    * 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:
       int minDepth(TreeNode* root) {
           if(root == nullptr)
               return 0;
           if(!root->left && !root->right)
               return 1;
           int leftDepth = 1 + minDepth(root -> left);
           leftDepth = ((leftDepth == 1)? INT_MAX : leftDepth);
           int rightDepth = 1 + minDepth(root -> right);
           rightDepth = ((rightDepth == 1) ? INT_MAX : rightDepth);
    
           return min(leftDepth, rightDepth);
    
       }
    };
  6. 镜像二叉树

    (1) 剑指offer

    给定一个二叉树,将其变换为原二叉树的镜像

    二叉树的镜像定义:源二叉树 
            8
           /  \
          6   10
         / \  / \
        5  7 9   11
        镜像二叉树
            8
           /  \
          10   6
         / \  / \
        11 9 7   5
    /*
    思路:将二叉树转换为镜像二叉树,可以使用递归的方法。如果输入节点为空,则返回;如果输入节点的左右子树都为空,则返回;否则将左右子树交换。如果左子树非空,则递归调用左子树;若右子树非空,则递归调用右子树。
    */
    struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
    };*/
    class Solution {
    public:
       void Mirror(TreeNode *pRoot) {
           if(pRoot == NULL)
               return;
           if(pRoot->left == NULL && pRoot->right == NULL)
               return;
           swap(pRoot->left,pRoot->right);
           if(pRoot->left!=NULL)
               Mirror(pRoot->left);
           if(pRoot->right!=NULL)
               Mirror(pRoot->right);
       }
    };

    (2) LeetCode 101

    给定一个二叉树,判断它是否是镜像的。

    例如,下面这个二叉树就是镜像的

       1
      / \
     2   2
    / \ / \
    3  4 4  3

    下面这个二叉树就是非镜像的

       1
      / \
     2   2
      \   \
      3    3
    /*
    思路:函数输入的是一个根节点,将如果根节点为空,则返回true;否则将根节点作为两个节点传入Mirror函数来判断。要是两个根节点都是空,则返回true,要是其中一个为空,则返回false;若两个节点的值不同,则返回false;否则,将第一个节点的左子树和第二个节点的右子树带入Mirror函数,同时将第一个节点的右子树和第二个节点的左子树带入Mirror函数,取两者的与。
    */
    /**
    * 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:
       bool isSymmetric(TreeNode* root) {
           if(root == NULL)
               return true;
           return MirrorTree(root,root);
       }
    
       bool MirrorTree(TreeNode* root1, TreeNode* root2)
       {
           if(!root1&&!root2)
               return true;
           if(!root1||!root2)
               return false;
           if(root1->val != root2->val)
               return false;
           return MirrorTree(root1->left,root2->right)&&MirrorTree(root1->right,root2->left);
       }
    };
  7. 不使用乘除法和控制语句的n个数求和

    剑指offer

    求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

    /*
    求1+2+3+...+n,要求不能使用乘除法、forwhileifelseswitch、case等关键字及条件判断语句(A?B:C)。
    思路:
    利用&&短路原理,并使用递归,可以实现求和的过程
    */
    class Solution {
    public:
       int Sum_Solution(int n) {
           int temp = n;
           temp && (temp+=Sum_Solution(temp-1));
           return temp;
       }
    };
  8. 反转链表

    LeetCode 206

    反转单链表

    输入:1->2->3->4->5->NULL

    输出:5->4->3->2->1->NULL

    /*
    思路:使用三个指针,一个指针用于存储当前节点,一个指针存储前一个节点,一个指针存储下一个节点。只要当前节点不为空,就将下一个节点当前节点的下一个节点存在临时变量中,然后将下一个节点更新为前一个节点,将前一个节点更新为当前节点,将当前节点更新为下一个节点。
    */
    /**
    * Definition for singly-linked list.
    * struct ListNode {
    *     int val;
    *     ListNode *next;
    *     ListNode(int x) : val(x), next(NULL) {}
    * };
    */
    class Solution {
    public:
       ListNode* reverseList(ListNode* head) {
           ListNode *cur = head;
           ListNode *pre = NULL;
           while(cur != NULL)
           {
               ListNode *temp = cur->next;
               cur->next = pre;
               pre = cur;
               cur = temp;
           }
           return pre;
       }
    };
  9. 质数判断

    判断质数常用的一种方法,就是从2开始,到sqrt(n)结束,如果都不能整除n,则此数为质数。

    class Solution{
    public:
       bool isPrime(int n)
       {
           for(int i = 2; i < sqrt(n); ++i)
           {
               if(n % i == 0)
                   return false;
           }
           return true;
       }
    };
  10. 最大公约数

    求最大公约数有两种方法:

    方法一:辗转相除

    /*
        思路:给定两个数a和b,使得a为较大的数,b为较小的数。如果a%b为0的话,b就是最大公约数;如果不为0,则将a更新为b,将b更新为a%b即可。
    */
    int gcd(int a, int b)
    {
        //首先进行a和b顺序确定
        if(a < b)
        {
            a = a + b;
            b = a - b;
            a = a - b;
        }
    
        c = a % b;
        while(a % b != 0)
        {
            a = b;
            b = c;
            c = a % b;
        }
        return b;
    }

    方法二:循环遍历

    /*
        思路:给定a、b两个数,将较小的数赋值给c,c = b(a > b),将a和b对c做求余操作,从c开始一次向下遍历,直到两者的余数都为0,否则c减1,继续循环遍历。
    */
    int gcd(int a, int b)
    {
        int c;
        c = (a > b) ? b : a;
        while(a % c != 0 || b % c != 0)
        {
            c--
        }
        return c;
    }
  11. 最小公倍数

    最小公倍数可以依靠最大公约数来求解,设c为a和b的最大公约数,则最小公倍数为a * b / c

    int LeastCommonMultiple(int a, int b)
    {
        return a * b / gcd(a , b);
    }
  12. 水仙花数

    遍历输入的数字,将数字存储啊在vector中,获得vector的长度即为指数,然后加和所有数字的长度次方与输入数对比即可。

    
    #include<iostream>
    
    
    #include<string>
    
    
    #include<vector>
    
    
    #include<math.h>
    
    
    using namespace std;
    bool isLegalNumber(int n);
    
    int main()
    {
        int num;
        while(cin>>num)
        {
            if(isLegalNumber(num))
                cout<<"true"<<endl;
            else
                cout<<"false"<<endl;
        }
    }
    
    bool isLegalNumber(int n)
    {
        int temp = n;
        vector<int> number;
    
        while(temp != 0)
        {
            number.push_back(temp % 10);
            temp = temp / 10;
        }
    
        int len = number.size();
        int ans = 0;
        for(int i = len - 1; i >= 0; --i)
        {
            int t = pow(number[i], len);
            ans = ans + t;
        }
        if(ans == n)
            return true;
        else
            return false;
    
    }
  13. 丑数

    LeetCode 263

    输入一个数,判断这个是否为丑数。丑数即因子只有2、3和5的数。

    /*
        思路:首先对边界数0进行操作,当输入为0时,输出false;
        然后对输入进行除2操作,直到不能被2整除,然后对其进行除3操作,直到不能整除,然后对其进行除5操作,直到不能整除。最后判断商是否为1,若为1则返回true,否则返回false。
    */
    class Solution {
    public:
        bool isUgly(int num) {
            if(num == 0)
                return false;
            while(num % 2 == 0)
                num /= 2;
            while(num % 3 == 0)
                num /= 3;
            while(num % 5 == 0)
                num /= 5;
            if(num == 1)
                return true;
            else
                return false;
        }
    };

    LeetCode 264

    输入一个数n,返回第n个丑数。

    /*
        思路:定义变量i,j,k分别表示2的因子的数,3的因子的数和5的因子的数,每次选择其中最小的数加入容器,最后返回容器顶部的数。
    */
    class Solution {
    public:
        int nthUglyNumber(int n) {
            int i = 0, j = 0, k = 0;
            vector<int> res(1,1);
            while(res.size() < n)
            {
                res.push_back(min(2 * res[i] , min(3 * res[j], 5 * res[k])));
                if(res.back() == res[i] * 2)
                    i++;
                if(res.back() == res[j] * 3)
                    j++;
                if(res.back() == res[k] * 5)
                    k++;
            }
            return res.back();
        }
    };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值