力扣100题——技巧

只出现一次的数字

题目

136. 只出现一次的数字 - 力扣(LeetCode)

思路

这题很有意思,考察的知识点也比较偏,涉及到位运算。

由于每个元素除了一个只出现一次外,其他元素都出现了两次,所以我们可以利用位运算中的异或操作来解决这个问题。

位运算(异或操作):
  • 异或操作(^)的性质:
    1. x ^ x = 0(任何数与自身异或为 0)
    2. x ^ 0 = x(任何数与 0 异或还是这个数)
    3. 异或运算满足交换律和结合律

基于上述性质,如果我们将数组中的所有数字都异或起来,成对出现的数字都会相互抵消,结果就是那个只出现一次的数字。

代码

java 复制代码
public int singleNumber(int[] nums) {
        int result = 0;
        // 遍历数组,将所有元素进行异或运算
        for (int num : nums) {
            result ^= num;
        }
        return result;
    }

多数元素

题目

169. 多数元素 - 力扣(LeetCode)

思路

Boyer-Moore 投票算法:

这个算法利用了多数元素的特性,可以在线性时间和常量空间复杂度下找到多数元素。

  • 算法的核心思路是维护一个候选多数元素 candidate 和计数器 count
    • 初始化时 candidatenullcount 为 0。
    • 当遍历到一个元素时:
      • 如果 count == 0,将当前元素设为 candidate,并将 count 设为 1。
      • 如果当前元素等于 candidate,则 count 增加 1。
      • 如果当前元素不等于 candidate,则 count 减少 1。
    • 由于多数元素出现次数超过一半,最终的 candidate 一定是多数元素。

代码

java 复制代码
public int majorityElement(int[] nums) {
        int count = 1;
        int candidate = nums[0];
        for(int i=1;i<nums.length;i++){
            if(count==0){
                candidate = nums[i];
            }
            if(nums[i]==candidate){
                count++;
            }else{
                count--;
            }
        }
        return candidate;
    }

颜色分类

题目

75. 颜色分类 - 力扣(LeetCode)

思路

使用双指针分别指向头部(low)和尾部(high),以及一个遍历指针 i

  • nums[i] == 0 时,交换 nums[i]nums[low],并让 lowi 向右移动。
  • nums[i] == 2 时,交换 nums[i]nums[high],并让 high 向左移动。
  • nums[i] == 1 时,i 向右移动即可。

通过这种方式,我们可以一次遍历将 0 移到前面,2 移到后面,1 自然排在中间

代码

java 复制代码
public void sortColors(int[] nums) {
       int top=0,tail=nums.length-1;
       int x=0;
       while(x<=tail){
           if(nums[x]==0){
               int t = nums[x];
               nums[x]=nums[top];
               nums[top]=t;
               top++;
               x++;
           }else if(nums[x]==2){
               int t = nums[x];
               nums[x]=nums[tail];
               nums[tail]=t;
               tail--;
           }else{
               x++;
           }
       }
    }

下一个排列

题目

31. 下一个排列 - 力扣(LeetCode)

思路

  • 从后往前找到第一个降序的数字 nums[i],即找到 nums[i] < nums[i+1] 的那个位置,这样的位置的右侧是需要调整的部分。
  • nums[i] 的右侧找到比 nums[i] 大的最小数字 nums[j],然后交换 nums[i]nums[j]
  • 交换后将 nums[i] 右侧的部分进行反转(从降序变为升序),得到的就是字典序的下一个排列。

代码

java 复制代码
public void nextPermutation(int[] nums) {
        int n = nums.length;
        int i = n - 2;
        while (i >= 0 && nums[i] >= nums[i + 1]) {
            i--;
        }
        if (i >= 0) {
            int j = n - 1;
            while (j >= 0 && nums[j] <= nums[i]) {
                j--;
            }
            swap(nums, i, j);
        }
        reverse(nums, i + 1, n - 1);
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

    private void reverse(int[] nums, int start, int end) {
        while (start < end) {
            swap(nums, start, end);
            start++;
            end--;
        }
    }

结语

这些题目对我的智商不太友好

相关推荐
前端小L5 小时前
贪心算法专题(十):维度权衡的艺术——「根据身高重建队列」
javascript·算法·贪心算法
方得一笔5 小时前
自定义常用的字符串函数(strlen,strcpy,strcmp,strcat)
算法
Xの哲學5 小时前
Linux SMP 实现机制深度剖析
linux·服务器·网络·算法·边缘计算
wuk9985 小时前
使用PCA算法进行故障诊断的MATLAB仿真
算法·matlab
额呃呃5 小时前
二分查找细节理解
数据结构·算法
无尽的罚坐人生6 小时前
hot 100 283. 移动零
数据结构·算法·双指针
永远都不秃头的程序员(互关)6 小时前
C++动态数组实战:从手写到vector优化
c++·算法
水力魔方7 小时前
武理排水管网模拟分析系统应用专题5:模型克隆与并行计算
数据库·c++·算法·swmm
谈笑也风生7 小时前
经典算法题型之排序算法(三)
java·算法·排序算法
大佬,救命!!!9 小时前
对算子shape相关的属性值自动化处理
python·算法·自动化·学习笔记·算子·用例脚本·算子形状