力扣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--;
        }
    }

结语

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

相关推荐
redcocal16 分钟前
地平线内推码 kbrfck
c++·嵌入式硬件·mcu·算法·fpga开发·求职招聘
.普通人1 小时前
c语言--力扣简单题目(链表的中间节点)讲解
c语言·leetcode·链表
西农小陈1 小时前
python-字符排列问题
数据结构·python·算法
TechQuester2 小时前
OpenAI 刚刚推出 o1 大模型!!突破LLM极限
人工智能·python·gpt·算法·chatgpt
__AtYou__2 小时前
Golang | Leetcode Golang题解之第412题Fizz Buzz
leetcode·golang·题解
西农小陈2 小时前
python-简单的数据结构
数据结构·python·算法
_Chocolate2 小时前
十大排序(一):冒泡排序
c语言·数据结构·算法
running thunderbolt2 小时前
C++:类和对象全解
c语言·开发语言·c++·算法
小陈的进阶之路3 小时前
c++刷题
开发语言·c++·算法
model20054 小时前
sahi目标检测java实现
java·算法·目标检测