手撕力扣之数学题:整数反转、回文数、Excel表列序号、阶乘后的零、各位相加、自除数、分糖果 II、3的幂、Nim 游戏、1比特与2比特字符、圆圈中最后剩下的数字、三个数的最大乘积、有效的正方形

力扣007. 整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
解法一:

class Solution {
public:
    int reverse(int x) {
        long res=0;
        while(x!=0)
        {
            int temp=x%10;
            res=res*10+temp;
            x/=10;
        }
        if(res>=INT_MAX||res<=INT_MIN)  return 0;
        return res;
    }
};

解法二:

class Solution {
public:
    int reverse(int x) {
        //2^31-1=2147483647,-2^31=-2147483648
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0;
            if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
};

作者:demigodliu
链接:https://leetcode-cn.com/problems/reverse-integer/solution/tu-jie-guan-fang-tui-jian-ti-jie-zheng-s-rh6b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣009. 回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

class Solution {
public:
    bool isPalindrome(int x) {
        if(x<0) return false;
        if(x==0) return true;
        long res=0;
        int y=x;
        while(x){
            res=res*10+x%10;
            x=x/10;
        }
        return (int)res==y?true:false;

    }
};

力扣171. Excel表列序号
给定一个Excel表格中的列名称,返回其相应的列序号。
A -> 1
B -> 2
C -> 3

Z -> 26
AA -> 27
AB -> 28

class Solution {
public:
    int titleToNumber(string s) {
        int res=0;
        for(int i=0;i<s.size();i++)
        {
            res=res*26+(s[i]-'A'+1);
        }
        return res;
    }
};

力扣172. 阶乘后的零
给定一个整数 n,返回 n! 结果尾数中零的数量。

求n!
0的来源 2 * 5 所以一对2和5即可产生一个0,所以0的个数即为min(阶乘中5的个数和2的个数) 
又因为是2的倍数的数一定比是5的倍数的数多 所以2的个数一定>=5的个数 所以只需要统计 5 的个数了
例如 5! = 1 * 2 * 3 * 4 * 5
              2      2 2  5    一个2和一个5配对出现0 所以5!末尾只有一个零
    而在 n = 25 时 可以产生5的有 5 10 15 20 25 
                                即 n/5 = 5个 然鹅 25 = 5*5 所以少算了一个5 
    n>=25时,故而需要补上它 因此所有可以产生25的也要加上 
                                即为 n/5 + n/25  然鹅 125 = 5*25 所以又少算了一个5
    n>=125时,故而需要补上它 因此所有可以产生125的也要加上
                                即为 n/5 + n/25 + n/125  然鹅 625 = 5*125 所以又少算了一个5
    继续补上...
    所以最终为 n/5 + n/25 + n/125 + n/625 + ... 
            即 n/5 + n/5/5 + n/5/5/5 + n/5/5/5/5 + ... 
int trailingZeroes(int n) {
        int five = 0;
        while(n >= 5){
            five += n/5;
            n/=5;
        }
        return five;
    }

作者:zeroac
链接:https://leetcode-cn.com/problems/factorial-trailing-zeroes/solution/c-shu-xue-xiang-xi-tui-dao-by-zeroac/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣258. 各位相加
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

class Solution {
public:
    int addDigits(int num) {
        while (num > 9)
        {
            int sum = 0;
            while (num)
            {
                int tmp = num % 10;
                sum += tmp;
                num /= 10;
            }
            num = sum;
        }
        return num;
    }
};

作者:Gary_coding
链接:https://leetcode-cn.com/problems/add-digits/solution/c-zhong-gui-zhong-ju-de-4msjie-fa-bao-li-mei-xue-b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣728. 自除数
自除数 是指可以被它包含的每一位数除尽的数。
例如,128 是一个自除数,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0。
还有,自除数不允许包含 0 。
给定上边界和下边界数字,输出一个列表,列表的元素是边界(含边界)内所有的自除数。

class Solution {
public:
    vector<int> selfDividingNumbers(int left, int right) {
        vector<int> res;
        for(int i = left; i <= right; ++i){
            int m = i;
            int n = i;
            int flag = 1;
            while(m != 0){
                if(m % 10 == 0){
                    flag = 0;
                    break;
                }
                if(n % (m % 10) != 0){
                    flag = 0;
                    break;
                }
                m /= 10;
            }
            if(flag)
                res.push_back(i);
        }
        return res;
    }
};

力扣1103. 分糖果 II
排排坐,分糖果。
我们买了一些糖果 candies,打算把它们分给排好队的 n = num_people 个小朋友。
给第一个小朋友 1 颗糖果,第二个小朋友 2 颗,依此类推,直到给最后一个小朋友 n 颗糖果。
然后,我们再回到队伍的起点,给第一个小朋友 n + 1 颗糖果,第二个小朋友 n + 2 颗,依此类推,直到给最后一个小朋友 2 * n 颗糖果。
重复上述过程(每次都比上一次多给出一颗糖果,当到达队伍终点后再次从队伍起点开始),直到我们分完所有的糖果。注意,就算我们手中的剩下糖果数不够(不比前一次发出的糖果多),这些糖果也会全部发给当前的小朋友。
返回一个长度为 num_people、元素之和为 candies 的数组,以表示糖果的最终分发情况(即 ans[i] 表示第 i 个小朋友分到的糖果数)。
模拟:最直观的方法是不断地遍历数组,如果还有糖就一直分,直到没有糖为止。

class Solution {
public:
    vector<int> distributeCandies(int candies, int num_people) {
        vector<int> ans(num_people,0);
        int i = 0;
        while (candies != 0) {
            ans[i % num_people] += min(candies, i + 1);
            candies -= min(candies, i + 1);
            ++i;
        }
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/distribute-candies-to-people/solution/fen-tang-guo-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣326. 3的幂
给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3^x

class Solution {
public:
    bool isPowerOfThree(int n) {
        if(n==1) return true;
        long m=1;
        while(m<n)
        {
            m*=3;
            if(m==n)
                return true;
        }
        return false;
    }
};

作者:chenlele
链接:https://leetcode-cn.com/problems/power-of-three/solution/3de-mi-by-gpe3dbjds1/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣292. Nim 游戏
你和你的朋友,两个人一起玩 Nim 游戏:
桌子上有一堆石头。
你们轮流进行自己的回合,你作为先手。
每一回合,轮到的人拿掉 1 - 3 块石头。
拿掉最后一块石头的人就是获胜者。
假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false 。
思路:
巴什博奕,n%(m+1)!=0时,先手总是会赢的
面对4的整数倍的人永远无法翻身,你拿N根对手就会拿4-N根,保证每回合共减4根,你永远对面4倍数,直到4. 相反,如果最开始不是4倍数,你可以拿掉刚好剩下4倍数根,让他永远对面4倍数。

 class Solution {
public:
    bool canWinNim(int n) {
        return n%4!=0;
    }
};

作者:angel_monica
链接:https://leetcode-cn.com/problems/nim-game/solution/shu-xue-gui-lei-fa-zheng-ming-by-vailing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣717. 1比特与2比特字符
有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。
现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。
思路:
1、由于只有三种字符"0",“10”,“11”,且没有某个字符是其他字符打前缀,所以已存在一种解码方式(类似于哈夫曼编码)
2、字符串的最后一位总是0
简单分析: 若这个由若干比特组成的字符串,最后一个字符为一个一比特字符,则去掉这个字符,这个字符串还是可以正常解码的(对应到代码中及就是出循环时i==bits.size()-1)

class Solution {
public:
    bool isOneBitCharacter(vector<int>& bits) {
        int i=0;
      for (;i<bits.size()-1;i++){
          if(bits[i]==1) i++;
      }
      if(i==bits.size()-1) return true;
      return false;   
    }
};

作者:ttods
链接:https://leetcode-cn.com/problems/1-bit-and-2-bit-characters/solution/1bi-te-yu-2bi-te-zi-fu-by-ttods/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣剑指 Offer 62. 圆圈中最后剩下的数字
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
思路:

f(N,M)=(f(N−1,M)+M)%N

约瑟夫环:理解这个递推式的核心在于关注胜利者的下标位置是怎么变的。每杀掉一个人,其实就是把这个数组向前移动了M位。然后逆过来,就可以得到这个递推式。

class Solution {
public:
    int lastRemaining(int n, int m) {
        int pos = 0; // 最终活下来那个人的初始位置
        for(int i = 2; i <= n; i++){
            pos = (pos + m) % i;  // 每次循环右移
        }
        return pos;
    }
};


作者:aspenstarss
链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/huan-ge-jiao-du-ju-li-jie-jue-yue-se-fu-huan-by-as/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

链表模拟法

class Solution {
public:
    struct ListNode
    {
        int val;
        ListNode* next;
        ListNode(int x)  :val(x),next(nullptr)  {}
    };

    ListNode* rebuild(int n)
    {
        ListNode* head=new ListNode(0);
        ListNode* cur=head;
        for(int i=1;i<n;i++)
        {
            ListNode* temp=new ListNode(i);
            cur->next=temp;
            cur=cur->next;
        }
        cur->next=head;
        return head;
    }
    int lastRemaining(int n, int m) {
        ListNode* head=rebuild(n);
        ListNode* p=head;
        ListNode* pre=nullptr;
        while(p->next!=p)
        {
            for(int i=1;i<m;i++)
            {
                pre=p;
                p=p->next;
            }
            pre->next=p->next;
            delete p;
            p=pre->next;
        }
        return p->val;
    }
};

力扣628. 三个数的最大乘积
给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。

class Solution {
public:
    int maximumProduct(vector<int>& nums) {
        // 最小的和第二小的
        int min1 = INT_MAX, min2 = INT_MAX;
        // 最大的、第二大的和第三大的
        int max1 = INT_MIN, max2 = INT_MIN, max3 = INT_MIN;

        for (int x: nums) {
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }

            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }
        }

        return max(min1 * min2 * max1, max1 * max2 * max3);
    }
};


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-product-of-three-numbers/solution/san-ge-shu-de-zui-da-cheng-ji-by-leetcod-t9sb/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

力扣593. 有效的正方形
给定二维空间中四点的坐标,返回四点是否可以构造一个正方形。
一个点的坐标(x,y)由一个有两个整数的整数数组表示。
思路:
四个顶点一共对应六条边,其中四条边,两条对角线,它们的关系应该是 四条边长相等, 两条对角线长相等,同时对角线长度的平方等于边长平方的两倍(勾股定理),利用这些关系即可判定是否满足正方形的条件

class Solution {
public:
    int distance2(vector<int>& p1, vector<int>& p2){
        return (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1]);
    }

    bool validSquare(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4) {
        bool valid = false;
        vector<int> length;
        length.push_back(distance2(p1, p2));
        length.push_back(distance2(p2, p3));
        length.push_back(distance2(p3, p4));
        length.push_back(distance2(p1, p3));
        length.push_back(distance2(p1, p4));
        length.push_back(distance2(p2, p4));

        sort(length.begin(), length.end());

        if (length[0] == 0) return false;
        // four + two 
        int side = length[0];
        for (int i = 1; i < 4; ++i){
            if (length[i] != side)
                return false;
        }

        int drop = length[4];
        if (length[4] != length[5])
            return false;

        if (2 * side != drop)
            return false;
        
        return true;
    }
};


作者:syric
链接:https://leetcode-cn.com/problems/valid-square/solution/tong-guo-si-tiao-deng-bian-chang-he-liang-tiao-dui/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值