当前位置: 首页 > news >正文

leetcode hot100 技巧

如有缺漏谬误,还请批评指正。

1.只出现一次的数字

利用异或运算相同得0的特点。所有出现过两次的数字都会在异或运算累加过程中被抵消。、

class Solution {
public:int singleNumber(vector<int>& nums) {int res=0;for(int i=0;i<nums.size();i++) res^=nums[i];return res;}
};

2.多数元素

        随机取数,然后判断是否是答案。因为众数被选中的概率大于50%,所以时间复杂度虽然理论上可能出现O(∞)的情况,但实际上可以达到O(n)。

class Solution {
public:int majorityElement(vector<int>& nums) {while(true){int candidate=nums[rand()%nums.size()];int count=0;for(int i=0;i<nums.size();i++){if(nums[i]==candidate){count++;if (count>nums.size()/2) return candidate;}}}return -1;}
};

3.颜色分类

        经典的“荷兰国旗”问题。

(1)单指针解法

class Solution {
public:void sortColors(vector<int>& nums) {int i=0;for(int j=0;j<nums.size();j++){if(nums[j]==0){swap(nums[i],nums[j]);i++;}}for(int j=i;j<nums.size();j++){if(nums[j]==1){swap(nums[i],nums[j]);i++;}}}
};

(2)双指针解法

        比单指针少了一趟遍历。

①两个同向指针分别记录0的交换位置和1的交换位置。

class Solution {
public:void sortColors(vector<int>& nums) {int n=nums.size();int ptr0=0,ptr1=0;for(int i=0;i<n;i++){if(nums[i]==0){swap(nums[i],nums[ptr0++]);if(ptr1<ptr0) ptr1++;}if(nums[i]==1) swap(nums[i],nums[ptr1++]);}}
};

②左右指针分别记录0的交换位置和2的交换位置。 

class Solution {
public:void sortColors(vector<int>& nums) {int n = nums.size();int r0=0,l2=n-1;  // r0: 0的右边界,l2:2的左边界for(int i=0;i<=l2;i++){       // 必须包含等于,因为nums[r]可能还没处理if(nums[i]==0) swap(nums[i],nums[r0++]);  // 0交换到左边,r0右移//换完后的理想状态:换过后nums[i]是1(1处在0的右边界和2的左边界之间)else if(nums[i]==2){swap(nums[i],nums[l2--]);  // 2交换到右边,l2左移if(nums[i]!=1) i--;  //num[i]==0的情况:2和0换,换过后的0需再换一遍到左边界//num[i]==2的情况:2和2换,换过后的2需重新处理}}}
};

4.下一个排列

三个关键步骤:

  • 找到 ii是第一个破坏从后向前升序的位置,这意味着nums[i]可以增大以得到更大的排列。

  • 找到 jnums[j] 是 i 之后比 nums[i] 大的最小数,交换后 nums[i]增大,但 i 之后的部分仍然降序。

  • 反转:反转 i+1之后的部分使其升序,这样这部分最小,确保了整个排列是“下一个”排列。

class Solution {
public:void nextPermutation(vector<int>& nums) {int n=nums.size();int i=n-2;// 1. 找到第一个不符合逆序升的nums[i]while(i>=0&&nums[i]>=nums[i+1]) i--;// 2. 再找第一个比nums[i]大的nums[j],swap两个数if(i>=0){int j=n-1;while(j>=0&&nums[j]<=nums[i]) j--;swap(nums[i], nums[j]);}// 3.反转 i+1 到末尾的部分(使其升序)reverse(nums.begin()+i+1, nums.end());}
};

5.多数问题

核心思想:将数组视为链表,并利用快慢指针检测环。

相遇的地点是环的入口(即重复数字):推导如下。

class Solution {
public:int findDuplicate(vector<int>& nums) {// 初始化快慢指针,初始位置在数组的起始位置(索引0)int slow=0,fast=0;// 第一阶段:检测环的存在(Floyd's Tortoise and Hare算法)do{slow=nums[slow];       // 慢指针每次移动一步fast=nums[nums[fast]]; // 快指针每次移动两步} while (slow!=fast);      // 当快慢指针相遇时,说明存在环// 第二阶段:找到环的入口(即重复的数字)slow=0; // 将慢指针重置到起点while(slow!=fast){slow=nums[slow]; // 慢指针每次移动一步fast=nums[fast]; // 快指针每次移动一步}// 最终相遇点就是重复的数字return slow;}
};

http://www.xdnf.cn/news/331651.html

相关文章:

  • C++函数栈帧详解
  • Ultralytics中的YOLODataset和BaseDataset
  • comfyui 实现中文提示词翻译英文进行图像生成
  • 低成本监控IPC模组概述
  • D盘出现不知名文件
  • int (*)[3]和int (*arr_ptr)[3]区别
  • Spark应用部署模式实例
  • 个人网站versionI正式上线了!Personal Website for Jing Liu
  • ✍️【TS类型体操进阶】挑战类型极限,成为类型魔法师!♂️✨
  • JAVA八股文
  • CI/CD与DevOps流程流程简述(提供思路)
  • 使用pdm管理python项目时去哪里找nuitka
  • 如何通过复盘提升团队能力?
  • 数组和集合
  • 【C++的类型转换】
  • 【漏洞预警】:致远OA V8.1 SP2 data.htm DOM型XSS漏洞
  • 使用 `detach()` 断开与共享特征层的连接
  • (已完结)完美解决C盘拓展卷是灰色的无法扩容的问题以及如何正确地在WINDOS上从一个盘扩容到C盘
  • Android 如何理解 Java JNI 中的引用与 Java 对象应用的区别
  • java算法的核心思想及考察的解题思路
  • Codeforces Round 1022 (Div. 2)
  • YOLOv1:开创实时目标检测新纪元
  • go.mod没有自动缓存问题
  • vue截图-html2canvas
  • 《硬件视界》专栏介绍(持续更新ing)
  • Qt学习Day2:信号槽
  • 从SQL的执行流程彻底详解预编译是如何解决SQL注入问题
  • Linux57配置MYSQL YUM源
  • 离散化(竞赛)
  • MinIo安装和使用操作说明(windows)