剑指offer 打卡计划 | 每日进步一点点 | 第二十五天

122 阅读1分钟

图片.png

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情

剑指 Offer 63. 股票的最大利润

思路

(贪心) O(n)

由于只允许做一次股票买卖交易,因此我们用minv记录一只股票的最低价格,之后遍历整个prices数组,更新minvprices[i] - minv的最大值。

时间复杂度分析: O(n)

c++代码

 class Solution {
 public:
     int maxProfit(vector<int>& prices) {
         if(!prices.size()) return 0;
         int res = 0,minv = INT_MAX;
         for(int i = 0; i < prices.size(); i++){
             minv = min(minv, prices[i]);  //记录一只股票的最低价格
             res = max(res, prices[i] - minv);
         }
         return res;
     }
 };
 ​

剑指 Offer 64. 求1+2+…+n

思路

(递归) O(n)

1 + 2 + ... + n,但是不能使用乘除法、forwhileifelseswitchcase等关键字及条件判断语句,因此考虑递归。 递归函数定义: int sumNums(int n)表示求1 + 2 + ... + n

递归等价式: sumNums(n) = n + sumNums(n - 1)

递归边界: n == 1时,返回1。但是题目要求不能使用ifwhile等分支判断,可以考虑利用&&短路运算来终止判断。

时间复杂度分析: O(n)

c++代码

 class Solution {
 public:
     int sumNums(int n) {
         int res = n;
         n >= 1 && (res += sumNums(n - 1));
         return res;
     }
 };

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

思路

(异或) O(1)

通过与运算与异或运算来实现加法运算:

  • 1、计算两个数不算进位的结果 (a ^ b)
  • 2、计算两个数进位的结果 (a & b) << 1
  • 3、将两个结果相加,我们发现又要用到加法运算,那么其实我们重复上述步骤就行了,直到一个数变为0( 不再进位 )则运算全部完成。

图片.png 时间复杂度分析: O(1)

c++代码

 class Solution {
 public:
     int add(int a, int b) {
         while(b){
             int x = a ^ b; //计算进位
             int y = (unsigned int)(a & b) << 1 ;  //计算进位,并防止溢出
             a = x;
             b = y;
         }
         return a;
     }
 };

剑指 Offer 66. 构建乘积数组

思路

(数组) O(n)

由题意可知:B[i]=A[0]×A[1]×…×A[i−1]×A[i+1]×…×A[n−1] 。

因此,我们可以通过两边遍历来实现:

  • 1、第一遍正向遍历,求出 B[i]=A[0]×A[1]×…×A[i−1]。
  • 2、第二遍反向遍历,求出B[i] *= A[n - 1]×A[n - 2]×…×A[i+1]。

最后我们返回B[]数组即可。

时间复杂度分析: 我们遍历了两次数组,因此时间复杂度为O(n)

c++代码

 class Solution {
 public:
     vector<int> constructArr(vector<int>& a) {
         int n = a.size();
         vector<int> res(n);
         for(int i = 0, p = 1; i < n; i++){  // 第一次算出 res[i] = a[0] * a[1] * ... * a[i - 1]
             res[i] = p;
             p *= a[i];
         }
         for(int i = n - 1, p = 1; i >= 0; i-- ){
             res[i] *= p;                   // 第二次算出 res[i] *= a[n - 1] * a[n - 2]*...* a[i + 1]
             p *= a[i];
         }
         return res;
     }
 };