Leetcode 29. 两数相除

298 阅读2分钟

Leetcode 29. 两数相除

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情

❤️‍欢迎订阅java厂长《LeetCode每日一题》 ❤️‍

1、题目📑

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

实例1

输入: dividend = 10, divisor = 3

输出: 3

解释: 10/3 = truncate(3.33333..) = truncate(3) = 3

实例2

输入: dividend = 7, divisor = -3

输出: -2

解释: 7/-3 = truncate(-2.33333..) = -2

提示

  • 被除数和除数均为 32 位有符号整数。
  • 除数不为 0。
  • 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

2、思路🧠

方法一

本题的难点在于负数越界问题。处理过程中,统一转化成负数来操作,防溢出,因为Integer.MIN_VALUE无法用正数表示

待完善!

  1. 特判:如果数组的为 null 或者 长度 < 3,直接返回空集合。
  2. 初始化:
    • 对数组先进行排序,排序后出现固定位置的数字大于0,则后面的数字不用进行考虑,直接结束
    • 确定固定指针 k ,定义双指针 ij
    • 求和结果sum,sum = nums[i] + nums[j] + nums[k];
  3. 循环遍历:
    • num[k] > 0 :因为已经排序,所以后面不可能出现三个数相加和等于 0 的情况,直接结束。
    • 重复元素:出现相同的元素,跳过
    • L<R 时,执行循环:
      • 若和大于 0 sum > 0,则说明 nums[j] 太大,j 左移
      • 若和小于 0 sum < 0,则说明 nums[i] 太小,i 右移
      • 若和等于 0 sum == 0,执行循环,去判断左和右数字是否与下一位置重复,目的是去除重复解。并同时将 ij 移到下一位置,寻找新的解
  4. 返回结果 res

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

class Solution {
    public int divide(int dividend, int divisor) {
        // 溢出情况
        if (dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        }

        // 记录结果的符号
        int sign = -1;
        if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) {
            sign = 1;
        }

        // 统一转化成负数来操作,防溢出。(Integer.MIN_VALUE无法用正数表示)
        dividend = dividend > 0? -dividend : dividend;
        divisor = divisor > 0 ? -divisor: divisor;

        int res = div(dividend, divisor);

        return sign < 0 ? -res : res;
    }

    public int div(int dividend, int divisor) {
        if(dividend > divisor) {
            return 0;
        }
        int cnt =1,d = divisor;
        // 不写成:d+d >= dividend 的形式,防止溢出 
        while(d >= dividend -d) {
            cnt = cnt + cnt;
            d = d + d;
        }
        return cnt + divide(dividend-d, divisor);
    }
}

时间复杂度:O(N2)

空间复杂度:O(1)

4、总结

该题目的对重复解的去重进行考察和练习,同时对于数组要有排序的敏感度,对双指针的解法也要非常的熟悉,并且能够想到具体问题具体解决。

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:29. 两数相除 - 力扣(LeetCode)