LeetCode 热题 HOT 100 打卡计划 | 第二十九天 | 每日进步一点点

102 阅读2分钟

图片.png

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

448. 找到所有数组中消失的数字

思路

(数组) O(n)

用负号识别当前数是否用过

1、遍历每个元素,对索引进行标记,将对应索引位置的值变为负数;

2、遍历下索引,看看哪些索引位置上的数不是负数的,位置上不是负数的索引,对应的元素就是不存在的。

图片.png 时间复杂度分析: 遍历两次数组,故时间复杂度为O(n)。

c++代码

 class Solution {
 public:
     vector<int> findDisappearedNumbers(vector<int>& nums) {
         vector<int> res;
         for(int x : nums){
             x = abs(x);
             if(nums[x - 1] > 0) nums[x - 1] *= -1;
         }
         for(int i = 0; i < nums.size(); i++){
             if(nums[i] > 0)
                 res.push_back(i + 1);
         }
         return res;
     }
 };

461. 汉明距离

思路

(位运算) O(logx)

1、先将xy作异或运算,异或运算之后,相同位为0,不同位为1

2、统计x ^ y1的个数。

时间复杂度分析: 异或的时间复杂度为 O(1),统计二进制位 1 的个数时间复杂度为 O(logx),故总时间复杂度为 O(logx)。

c++代码

 class Solution {
 public:
     int hammingDistance(int x, int y) {
         int n = x ^ y;   //相同位为0,不同位
         int res = 0;
         while(n){
             n -= n & -n; //lowbit
             res++;
         }
         return res;
     }
 };

494. 目标和

思路

(动态规划, 01背包) O(n * s)

状态表示: f[i][j]表示从nums数组的前i个数中选,且总和是j的方案数。

状态计算:

对于最后一个选择的数字nums[i],我们可以取正也可以取负,因此有两种方案:

  • 取正,则f[i][j] = f[i - 1][j - nums[i]]
  • 取负,则f[i][j] = f[i - 1][j + nums[i]];

两种方案数相加,状态转移方程为 f[i][j] = f[i - 1][j - nums[i]] + f[i - 1][j + nums[i]]

实现细节:

由于-1000 <= target <= 1000,因此j可能会取到负数,为了避免负数,在这里我们需要加上偏移量Offset

初始化: f[0][0] = 1,从前0个数中选,和为0的方案数为1

时间复杂度分析: 状态数量为O(n * s),状态计算为O(1),故总的时间复杂度为O(n * s)。

c++代码

 class Solution {
 public:
     // 动态规划
     int findTargetSumWays(vector<int>& nums, int target) {
         int n = nums.size(), Offset = 1000;  // offset为偏移量
         vector<vector<int>> f(n + 1, vector<int>(2000 + 10));
         f[0][Offset] = 1;  //对应f[0][0] = 1, 前0个数,和为0的方案数为1
         for(int i = 1; i <= n; i++){
             for(int j = - 1000; j <= 1000; j++){
                 if(j - nums[i - 1] >= -1000)
                     f[i][j + Offset] += f[i - 1][j + Offset - nums[i - 1]];
                 if(j + nums[i - 1] <= 1000)
                     f[i][j + Offset] += f[i - 1][j + Offset + nums[i - 1]];    
             }
         }
         return f[n][target + Offset];
     }
 };