[小玄的刷题日记]《LeetCode零基础指南》(第二讲) 函数

简介: [小玄的刷题日记]《LeetCode零基础指南》(第二讲) 函数

371.两整数之和

1.两整数之和 1.png


1.两整数之和

intgetSum(inta, intb){
returna + b;
}

2,位运算

预备知识:有符号的整数通常使用补码来表示和存储。补码具有以下特性:

  1. 正整数的补码与原码相同;负整数的补码为其原码除符号位外的所有位取反后+1
  2. 可以将减法运算转换为补码的加法运算来实现
  3. 符号位与数值位可以一起参与运算2.png

异或相当于一次无进位加法。来看一个例子3.png

a ^ b得到了一个无进位加法运算结果,如果要得到 a + b 的结果的最终值,我们还要找到进位的数,把这二者相加

我们可以用操作获得进位

4.png

由计算结果可见,0100 并不是我们想要的进位,1 + 1所获得的进位应该放在它的更高位,即在左侧位上,因此我们还要将 0100 左移一位,这才是我们所要的进位结果

总结一下:

  1. a + b 的问题拆分为(a + b 的无进制位结果)( a + b 的进制位结果)
  2. 无进位加法使用异或计算得出
  3. 进位结果使用与运算移位运算得出
  4. 循环此过程,直到进位为 0
intgetSum(inta, intb){
intc = 0;
while(b)
    {
c = (unsignedint)(a & b) << 1;
a ^= b;
b = c;
    }
returna;
}

面试题 17.01. 不用加号的加法 - 力扣(LeetCode) (leetcode-cn.com)

1,正常做法5.png2,位运算 6.png

intAdd(inta, intb){
intc = 0;
while(b)
    {
c = (unsignedint)(a & b) << 1;
a ^= b;
b = c;
    }
returna;
}

思路参考第一题

剑指 Offer 65. 不用加减乘除做加法 - 力扣(LeetCode) (leetcode-cn.com)

此题的解法也类似上面两道题


面试题 08.05. 递归乘法 - 力扣(LeetCode) (leetcode-cn.com)

7.png

对于这一题,我们可以采用暴力的方法直接 return a * b

不过,我们也可以按照题目的意思来操作一下下。8.png

intmultiply(intA, intB){
intresult; 
if (B > 1)
result = multiply(A, B-1) + A;
elseresult = A;
returnresult;
}

递归使用乘法函数,相当于b次的a相加

方法二

基本情况:

  1. B = 0 , 结果 == 0
  2. B = 1 , 结果 == A

考虑B为偶数的情况

res = A * ( B / 2) +  A * ( B / 2)

B为奇数时,只要在原本的结果上再加上 A 即可

intmultiply(intA, intB){
if(B == 0) return0;
if(B == 1) returnA;
intC = 0;
if(B & 1 > 0) //表示B为奇数
    {
C = A;
    }
returnmultiply(A , B >> 1) + multiply(A , B >> 1) + C;
}

29. 两数相除 - 力扣(LeetCode) (leetcode-cn.com)9.png

题目规定了【只能存储32位整数】,如果我们使用64位整数,可以极大地方地方便我们的代码,但这是违反题目规则的。

如果除法结果溢出,我们需要返回  2(31)- 1

  1. 当除数为32位有符号整数的最小值-2(31) - 1时,如果除数为1,我们直接返回         -2(31)  ||   如果除数为-1,那么答案为 2(31),产生了溢出,我们需要返回的值为2(31) - 1
  2. 当被除数为0时,我们可以直接返回0

于是,年幼的我们选择了

向大佬学习

intdivide(intdividend, intdivisor){
intcnt = 0;
intsign = 1;
if ((dividend ^ divisor) < 0) { // 两数任意一个为负数
sign = -1;
    }
if (divisor == INT_MIN) { // 除数边界值特殊处理
if (dividend == INT_MIN) {
return1;
        } else {
return0;
        }
    }
if (dividend == INT_MIN) { // 被除数边界值特殊处理
if (divisor == -1) {
returnINT_MAX;
        } elseif (divisor == 1) {
returnINT_MIN;
        }
dividend += abs(divisor); // 先执行一次加操作,避免abs转换溢出
cnt++;
    } 
inta = abs(dividend);
intb = abs(divisor);
while (a >= b) {
intc = 1;
ints = b;
        // 需指数级快速逼近,以避免执行超时
while (s < (a >> 1)) { // 逼近至一半,同时避免溢出
s += s;
c += c;
        }
cnt += c;
a-= s;
    }
return (sign == -1) ? -cnt : cnt;
}

50. Pow(x, n) - 力扣(LeetCode) (leetcode-cn.com)10.png

我尝试使用了常规的思路如下

doublemyPow(doublex, intn){
doublesum = 1;
inti = 0;
if(n == 0)
return1.0;
if(n > 0)
    {
for(i = 1;i <= n;i++)
sum *= x;
    }
if(n < 0)
    {
x = 1.0 / x;
for(i = 1;i <= -n;i++)
sum *= x;
    }
returnsum;
}

不过时间复杂度太高,运行超时。后来去学习了大佬的解法如下:

方法一 :递归

doublemyPow(doublex, intn){
if (n == 0) return1;
if (n == 1) returnx;
if (n ==-1) return1/x;
doubletemp = myPow(x, n / 2);
returntemp * temp * myPow(x, n % 2);
}

方法二:迭代

doublemyPow(doublex, intn){
doubleres = 1.0;
if (n < 0) x = 1/x;
while (n) {
if (n & 1) res = res * x;   //括号内等同(n % 2)
x = x * x;
n = n / 2;
    }
returnres;
}

方法三:快速幂

快速幂的本质是分治算法 。

举个例子:

11.png

从x开始,直接将上一次的结果进行平方,计算6次就能得到x(64)次方,而不需要对x*63次x12.png从左到右进行推导看上去比较困难,因为在每一步中,我们不知道在将上一次的结果平方后是否还需要*x。如果我们从右往左看,分治的思想就很明显了。


当我们要计算 时,我们可以先递归计算出 y =  ,其中[n /2 ]表示对a进行向下取整

根据递归的结果,如果n为偶数,你们  =  ;如果n为奇数,那么 = * x

递归的边界为 n = 0,任意数的 0次方 为1

classSolution {
public:
doublequickMul(doublex, longlongN) {
if (N == 0) {
return1.0;
        }
doubley = quickMul(x, N / 2);
returnN % 2 == 0 ? y * y : y * y * x;
    }
doublemyPow(doublex, intn) {
longlongN = n;
returnN >= 0 ? quickMul(x, N) : 1.0 / quickMul(x, -N);
    }
};

69. Sqrt(x) 题解 - 力扣(LeetCode) (leetcode-cn.com)

13.png

(卷不动了)


面试题 16.07. 最大数值 - 力扣(LeetCode) (leetcode-cn.com)14.png没什么好说的了,三目操作符yyds


今天的LeetCode之旅到此结束,希望能跟英雄哥继续努力学习,不断提高自己!!

目录
相关文章
|
5月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
6月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
145 2
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
99 1
|
5月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
6月前
|
算法 Python
【Leetcode刷题Python】 LeetCode 2038. 如果相邻两个颜色均相同则删除当前颜色
本文介绍了LeetCode 2038题的解法,题目要求在一个由'A'和'B'组成的字符串中,按照特定规则轮流删除颜色片段,判断Alice是否能够获胜,并提供了Python的实现代码。
69 3
|
6月前
|
Python
【Leetcode刷题Python】50. Pow(x, n)
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
38 1
|
6月前
|
Python
【Leetcode刷题Python】LeetCode 478. 在圆内随机生成点
本文介绍了LeetCode 478题的解法,题目要求在给定圆的半径和圆心位置的情况下实现在圆内均匀随机生成点的功能,并提供了Python的实现代码。
46 1
|
6月前
|
算法 Python
【Leetcode刷题Python】295. 数据流的中位数
本文介绍了一种使用Python实现的数据结构,用以支持数据流中添加整数并返回当前所有元素的中位数,通过排序列表来计算中位数。
47 1
|
6月前
|
算法 Python
【Leetcode刷题Python】73. 矩阵置零
本文介绍了LeetCode第73题的解法,题目要求在给定矩阵中将所有值为0的元素所在的行和列全部置为0,并提供了一种原地算法的Python实现。
53 0
【Leetcode刷题Python】73. 矩阵置零
|
6月前
|
Python
【Leetcode刷题Python】1467. 两个盒子中球的颜色数相同的概率
本文介绍了LeetCode第50题"Pow(x, n)"的解法,题目要求实现计算x的n次幂的函数,文章提供了递归分治法的详细解析和Python实现代码。
75 0