【思路详解+详细注释】小白都能看懂的力扣算法详解——技巧篇

一 LC136.只出现过一次的数字

题目要求:

给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

思路分析:

       这道题目其实好像也是很经典的一道题目,经常会出现在面试中。看到题目其实很多人第一反应就是哈希或者暴力(比如我...),但是本题要求了时间复杂度和空间复杂度。这时就要用到我们从学习编程语言第一课就学习过,但是往往被我们遗忘的位运算了。这道题的难度也就在这里,只要能想到用位运算,就没什么难点了。

        异或运算的特性:

  • x ^ x = 0:任何数字与自己异或结果为 0。
  • x ^ 0 = x:任何数字与 0 异或结果为自己。
  • 满足交换律和结合律。

        本题中,我们只要遍历数组中的每个元素,将它们依次与 result 进行异或操作。由于相同的数字异或结果为 0,最终 result 就是那个只出现一次的数字 。

完整代码示例:

class Solution {
    public int singleNumber(int[] nums) {
         int result = 0;
        // 遍历数组,使用异或运算
        for (int num : nums) {
            result ^= num;
        }
        return result;
    }
}

二 LC169.多数元素

题目要求:

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

思路分析:

       我们假设数组中总存在一个“多数元素”,它出现的次数比其他所有元素加起来还要多,因此可以通过消除不同的元素,最终得到多数元素。

        首先我们用一个变量 candidate 来存储当前的候选多数元素,并用 count 来统计当前候选元素的支持度。当遇到和 candidate 相同的元素时,count 增加;遇到不同的元素时,count 减少。当 count 为 0 时,说明当前候选元素已经被“抵消”了,需要重新选择一个候选多数元素。最终,candidate 就是多数元素。

完整代码示例:

class Solution {
    public int majorityElement(int[] nums) {
        int candidate = nums[0];
        int count = 1;

        // 选出候选多数元素
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == candidate) {
                count++;
            } else {
                count--;
            }

            if (count == 0) {
                candidate = nums[i];
                count = 1;
            }
        }
        return candidate;
    }
}

三 LC75.颜色分类

题目要求:

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

思路分析:

       我们可以维护三个指针:

        low:用于表示0的边界(红色区域的右边界)。

        mid:用于扫描数组。

        high:用于表示2的边界(蓝色区域的左边界)。

         mid指向数组首个元素,high执行数组末尾。遍历数组,当mid指向的元素等于0时,将mid和low位置的元素交换,并将low和mid都向右移动;当nums[mid] == 1时,只移动 mid。当mid指向的元素等于2时,将mid和high位置的元素交换,并将mid向右移动。直到mid大于high时,结束循环。

完整代码示例:

class Solution {
    public void sortColors(int[] nums) {
         int low = 0;
        int mid = 0;
        int high = nums.length - 1;

        // 遍历数组
        while (mid <= high) {
            if (nums[mid] == 0) {
                // 如果遇到0,将它交换到low位置,并将low和mid指针都向右移动
                swap(nums, low, mid);
                low++;
                mid++;
            } else if (nums[mid] == 1) {
                // 如果遇到1,直接将mid指针向右移动
                mid++;
            } else if (nums[mid] == 2) {
                // 如果遇到2,将它交换到high位置,并将high指针向左移动
                swap(nums, mid, high);
                high--;
            }
         }
    }
     private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值