【Leetcode 29】Divide Two Integers 不需要long的方法

【Description】

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

用例:

-2147483648 -2147483648
1 1
12 0
99 10
199999 1000
283923892 238923
-9 -10
9 10
-9 1
2147483647 1
-2147483648 1
-2147483648 -1
1 -1
-1 1
-1 -1

【Solution】

方法其实可以说是很low了,甚至可以说是面向用例的编程。 甚至让我一度跑去翻了汇编原理的书。

但是很奇妙的是结果跑到了90.68%前面。

题目说两个整数相除,一般人的做法都是:更大的整数类型。我就不相信了,应该有个不用long long的方法吧。

问题主要在我们把输入a,b都转成绝对值,然后进行移位计算除法,这样就会导致无法用INT_MIN的绝对值了(溢出了,-INT_MIN照样是INT_MIN)。

C++里移位直接就变成了int, 不能变成long long的类型。

这样,解决的方法是:

1. 对INT_MIN不能比较的特例进行表示, 对其他任何样例都可以正常编程。

2. 用unsigned int 将a, b进行转换,就可以表示INT_MAX了。比如 INT_MIN 转换成 1 << 31 的正整数形式, 而且用 unsigned int a = 1 << 31, 会有 a > INT_MAX。如果不转只能是a < INT_MAX甚至 a < 0。

复制代码
#include<iostream>
#include<limits.h>
using namespace std;
class Solution {
public:
    int divide(int a, int b) {
        if (b == 0 || (a == INT_MIN && b == -1)) {
            return INT_MAX;
        }
        if (a == INT_MIN && a == b) {
            return 1;
        }
        if (a == 0) {
            return 0;
        }
        int k = 1;
        if (a < 0 && b > 0) {
            k = -1;
        }
        else if (a > 0 && b < 0) {
            k = -1;
        }
        unsigned int dvd = a > 0 ? a : -a;
        unsigned int dvs = b > 0 ? b : -b;
        int div = 0, res = 0;
        // 强制设置dvd成unsigned int,在使用>=运算符时,会按照unsigned进行比较,这样可以表示1<<31 即 INT_MAX+1且其大于其它数(都<=INT_MAX)
        while (dvd >= dvs) {
            div = 0;
            while (dvd >= (dvs << div) && div < 31) {
                div++;
            }
            div--;
            dvd = dvd - (dvs << div);
            res += 1 << div;
        }
        res = k == 1 ? res : -res;
        return res;
    }
};
int main() {
    Solution sol;
    int x, y;while (cin >> x >> y)
    cout << sol.divide(x, y) << endl;
    return 0;
}
复制代码

 

posted @   stackupdown  阅读(161)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示