当前位置: 首页 > 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;}
};

相关文章:

  • ChatGPT-4o:临床医学科研与工作的创新引擎
  • maven基本介绍
  • influxdb实战
  • 三、Hadoop1.X及其组件的深度剖析
  • MATLAB的cvpartition函数用法
  • 基于Matlab实现耦合模理论仿真程序
  • 为了结合后端而学习前端的学习日志(1)——纯CSS静态卡片案例
  • STM32 CAN总线
  • 图片文件转base64存储在数据库
  • 【Python Number(数字)】
  • 性能优化-初识(C++)
  • 自定义Widget开发:手势交互处理
  • ES6入门---第三单元 模块五:Map和WeakMap
  • CentOS 安装 Zellij 终端复用器教程
  • WHAT - Rust 静态派发(Static Dispatch)和 动态派发(Dynamic Dispatch)
  • 【MongoDB篇】MongoDB的分片操作!
  • HTB - Eureka记录
  • 如何使用极狐GitLab 软件包仓库功能托管 maven?
  • 【JS逆向基础】WEB自动化
  • 给小白的AI Agent 基本技术点分析与讲解
  • 巴基斯坦全面恢复领空开放
  • 4月证券私募产品备案量创23个月新高,股票策略占比超六成
  • 四川资阳市原市长王善平被双开,“笃信风水,大搞迷信活动”
  • 新华时评:直播间里“家人”成“韭菜”,得好好管!
  • 陕西永寿4岁女童被蜜蜂蜇伤致死,当地镇政府介入处理
  • 最快3天开通一条定制公交线路!上海推出服务平台更快响应市民需求