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无法用正数表示
待完善!
- 特判:如果数组的为
null或者 长度 < 3,直接返回空集合。 - 初始化:
- 对数组先进行排序,排序后出现固定位置的数字大于0,则后面的数字不用进行考虑,直接结束
- 确定固定指针
k,定义双指针i,j - 求和结果
sum,sum = nums[i] + nums[j] + nums[k];
- 循环遍历:
- 若
num[k] > 0:因为已经排序,所以后面不可能出现三个数相加和等于 0 的情况,直接结束。 - 重复元素:出现相同的元素,跳过
- 当
L<R时,执行循环:- 若和大于 0
sum > 0,则说明 nums[j] 太大,j 左移 - 若和小于 0
sum < 0,则说明 nums[i] 太小,i 右移 - 若和等于 0
sum == 0,执行循环,去判断左和右数字是否与下一位置重复,目的是去除重复解。并同时将i,j移到下一位置,寻找新的解
- 若和大于 0
- 若
- 返回结果
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基础算法题》欢迎订阅❤️
厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。
对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!