三月秋冬的力扣刷题笔记(持续更新)

1.前言

本人只是一个普通学校的平凡不知名学生,学着软件工程专业目前大二,成绩不名列前茅。今日惊醒发现自己不能再咸鱼下去了,要多点学习一些关于编程的知识。在此情况下想着学习还得要多做笔记的,但毕竟自己是个学电脑的总不能手写笔记记录吧,花费时间和花费力气,重新回头复习难找的等等问题都太麻烦了。最后打算在CSDN这发表博客记录一下自己的学习笔记也当是让自己学习自律一下,同时也能分享给他人,虽然没有各大佬那样文章教学的好但起码也能帮助到诸位一点点。该文章会根据本人的学习情况进行更新,学到什么感觉有用的都会往这上面进行记录。
本文章收录的内容大部分参考至网上各平台大佬博主的文章,同时也会经过自己的修改再发布,每处参考部分本人都会表明作者和原处链接。本人只为记录和分享下自己的学习经历和记录学习笔记,不作任何盈利行为。
本文章将分为三个种类型题目进行分类,分别是简单、中等、困难。

2.参考文章的作者和原文链接:

参考作者【墨鳌】原文链接: 面试题 08.05. 递归乘法 - 力扣(Leetcode)
参考作者 克利斯提亚诺-梅西 原文链接: (3条消息) 【力扣面试】面试题 08.05. 递归乘法_克利斯提亚诺-梅西的博客-CSDN博客

3.简单

3-1.剑指 Offer 57 - II. 和为s的连续正数序列

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
示例 1:
输入:target = 9
输出:[[2,3,4],[4,5]]
示例 2:
输入:target = 15
输出:[[1,2,3,4,5],[4,5,6],[7,8]]

限制:
1 <= target <= 10^5
代码:
class      Solution {
public:
         vector<vector<int>> findContinuousSequence(int target) {
             vector<vector<int>> vec;//用vector容器创造一个储存数组(res)的数组
             vector<int> res;//用vecetor容器创造一个数组res
             int lo = 1;//lo指向res数组的第一个元素,初始时候
             int hi = 2;//hi指向res数组的第二个元素,初始时候
             while(hi<target){//while循环结束条件是hi指向target的时候
                 int curSum = (lo + hi) * (hi - lo + 1) / 2;//curSum是等差数列                                                                 的总和
                 if(curSum > target){//当总和大于target时lo向前一位
                     lo += 1;
                 }
                 if(curSum < target){//当总和小于target时hi向前一位
                     hi += 1;
                 }
                 if(curSum == target){//当总和等于target时
                     res.clear();//res数组清空
                     for(int k =      lo;k <= hi;k++){//进入for循环k初始位置是lo结                                                       束位置是大于hi时
                         res.emplace_back(k);//向res数组塞入(lo,hi)位置的数据
                     }
                     vec.emplace_back(res);//再把res数组的数据塞入vec数组
                     lo += 1;//然后lo自增,进行下一个循环
                 }
        }
          return vec;//直到while循环结束条件是hi指向target的时候返回vec数组
    }
};

3-2.面试题 17.01. 不用加号的加法

设计一个函数把两个数字相加。不得使用+ 或者其他算术运算符。
示例:
输入: a =1, b = 1
输出: 2

提示:
a, b 均可能是负数或 0
结果不会溢出 32 位整数
    1- class Solution {
    2- public:
    3-     vector<vector<int>> findContinuousSequence(int target) {
    4-         vector<vector<int>> vec;//1- 用vector容器创造一个储存数组(res)的数组
    5-         vector<int> res;//用vecetor容器创造一个数组res
    6-         int lo = 1;//lo指向res数组的第一个元素,初始时候
    7-         int hi = 2;//hi指向res数组的第二个元素,初始时候
    8-         while(hi<target){//while循环结束条件是hi指向target的时候
    9-             int curSum = (lo + hi) * (hi - lo + 1) / 2;//curSum是等差数                                                                   列的总和
    10-             if(curSum > target){//当总和大于target时lo向前一位
    11-                 lo += 1;
    12-             }
    13-             if(curSum < target){//当总和小于target时hi向前一位
    14-                 hi += 1;
    15-             }
    16-             if(curSum == target){//当总和等于target时
    17-                 res.clear();//res数组清空
    18-                 for(int k = lo;k <= hi;k++){//进入for循环k初始位置是lo结                                                         束位置是大于hi时
    19-                     res.emplace_back(k);//向res数组塞入(lo,hi)位置的数据
    20-                 }
    21-                 vec.emplace_back(res);//再把res数组的数据塞入vec数组
    22-                 lo += 1;//然后lo自增,进行下一个循环
    23-             }
    24-         }
    25-      return vec;//直到while循环结束条件是hi指向target的时候返回vec数组
    26-     }
};

3-3.剑指 Offer 65. 不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。
示例:
输入: a = 1, b = 1 输出: 2
提示:
a, b 均可能是负数或 0
结果不会溢出 32 位整数
    1. int getSum(int a, int b){
    2.     while(b != 0){
    3.         unsigned int carry = (unsigned int)(a & b) << 1;
    4.         a = a ^ b;
    5.         b = carry; 
    6.     }
    7.     return a;
}

4.中等

4-1. 29. 两数相除

给定两个整数,被除数 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 位有符号整数,其数值范围是[ ]
。本题中,如果除法结果溢出,则返回
    1- class Solution {
    2- public:
    3-     vector<vector<int>> findContinuousSequence(int target) {
    4-         vector<vector<int>> vec;//用vector容器创造一个储存数组(res)的数组
    5-         vector<int> res;//用vecetor容器创造一个数组res
    6-         int lo = 1;//lo指向res数组的第一个元素,初始时候
    7-         int hi = 2;//hi指向res数组的第二个元素,初始时候
    8-         while(hi<target){//while循环结束条件是hi指向target的时候
    9-             int curSum = (lo + hi) * (hi - lo + 1) / 2;//curSum是等差数                                                                   列的总和
    10-             if(curSum > target){//当总和大于target时lo向前一位
    11-                 lo += 1;
    12-             }
    13-             if(curSum < target){//当总和小于target时hi向前一位
    14-                 hi += 1;
    15-             }
    16-             if(curSum == target){//当总和等于target时
    17-                 res.clear();//res数组清空
    18-                 for(int k = lo;k <= hi;k++){//进入for循环k初始位置是lo结                                                         束位置是大于hi时
    19-                     res.emplace_back(k);//向res数组塞入(lo,hi)位置的数据
    20-                 }
    21-                 vec.emplace_back(res);//再把res数组的数据塞入vec数组
    22-                 lo += 1;//然后lo自增,进行下一个循环
    23-             }
    24-         }
    25-      return vec;//直到while循环结束条件是hi指向target的时候返回vec数组
    26-     }
    27- };

4-2. 371. 两整数之和

给你两个整数 a 和 b ,不适用运算符 + 和 - ,计算并返回两整数之和。
示例 1:
输入:a = 1, b = 2
输出:3

示例 2:
输入:a = 2, b = 3
输出:5

提示:
-1000 <= a, b <= 1000

参考题目讲解:
思路和算法
虽然题目只要求了不能使用运算符 + 和 - ,但是原则上来说也不宜使用类似的运算符+= 和 -= 以及sum 等方法。于是,我们使用位运算来处理这个问题。

首先,考虑两个二进制位相加的四种情况如下:
异或
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0 (进位)
可以发现,对于整数 a 和 b
在不考虑进位的情况下,其无进位加法结果为 a⊕b(异或)
而所有需要进位的位为 a &b,进位后的进位结果为(a & b)<< 1。
    1. int getSum(int a, int b){
    2.     while(b != 0){
    3.         unsigned int carry = (unsigned int)(a & b) << 1;
    4.         a = a ^ b;
    5.         b = carry; 
    6.     }
    7.     return a;
}

4-3.剑指 Offer 64. 求1+2+…+n

求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
示例 1:
输入: n = 3
输出: 6
示例 2:
输入: n = 9
输出: 45

限制:
1 <= n <= 10000
    1. int sumNums(int n){
    2.     bool arr[n][n+1];
    3.     return sizeof(arr)>>1;
}

4-4.面试题 16.01. 交换数字

编写一个函数,不用临时变量,直接交换numbers = [a, b]中a与b的值。

示例:
输入: numbers = [1,2]
输出: [2,1]

提示:
numbers.length == 2
-2147483647 <= numbers[i] <= 2147483647
1- 方法一:
    1. class Solution {
    2. public:
    3.     vector<int> swapNumbers(vector<int>& numbers) {
    4.         numbers[0]^=numbers[1];
    5.         numbers[1]^=numbers[0];
    6.         numbers[0]^=numbers[1];
    7.         return numbers;
    8.     }
};
引入异或运算
0^0 0
1^1 0
0^1 1
1^0 1
也就是对于 0 和 1,相同的数异或为 0,不同的数异或为 1。
这样就有了三个比较清晰的性质:
两个相同的十进制数异或的结果一定位零。
任何一个数和 0 的异或结果一定是它本身。
异或运算满足结合律和交换律。
我们直接来看(1) 和 (2) 这两句话,相当于b等于a ^ b ^ b,根据异或的几个性质,我们知道,这时候的b的值已经变成原先a的值了。
而再来看最后一句话,相当于a等于a ^ b ^ a,还是根据异或的几个性质,这时候,a的值已经变成了原先b的值。
从而实现了变量a和b的交换。
1- 方法二:

class Solution {
public:
    vector<int> swapNumbers(vector<int>& numbers) {
        numbers[0] = numbers[0] + numbers[1];
        numbers[1] = numbers[0] - numbers[1];
        numbers[0] = numbers[0] - numbers[1];
        return numbers;
    }
};
缺点比如说int整型数据的话有可能会相加溢出

4-5.面试题 08.05. 递归乘法

递归乘法。 写一个递归函数,不使用 * 运算符, 实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。

示例1:
输入:A = 1, B = 10 输出:10
示例2:
输入:A = 3, B = 4 输出:12

提示:
保证乘法范围不会溢出
方法一:运用二维数组,求数组的长度空间。
class Solution {
public:
    int multiply(int A, int B) {
        bool a[A][B];
        return (int)sizeof(a);
    }
};
方法二:通过位运算递归,加A次B。
int multiply(int A, int B){
    if(A>B){//将A的值和B的值交换
        A = A ^ B;
        B = A ^ B;
        A = A ^ B;
    }
    if(A>0){//判断A大于0进入
        return B + multiply(A-1,B);//递归一次A的值减一次,B的值加一次B
    }
    return 0;
}

4-6. 29. 两数相除

给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。
整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。
返回被除数 dividend 除以除数 divisor 得到的 商 。
注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [ , − 1] 。本题中,如果商 严格大于 − 1 ,则返回 − 1 ;如果商 严格小于 ,则返回

示例 1:
输入: dividend = 10, divisor = 3 输出: 3 解释: 10/3 = 3.33333.. ,向零截断后得到 3 。
示例 2:
输入: dividend = 7, divisor = -3 输出: -2 解释: 7/-3 = -2.33333.. ,向零截断后得到 -2 。

提示:
<= dividend, divisor <= - 1
divisor != 0
class Solution {
public:
    int divide(int dividend, int divisor) {

    }
};

5.困难

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值