LeetCode:经典题之389 题解与延伸

2024-06-24 08:20

本文主要是介绍LeetCode:经典题之389 题解与延伸,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

系列目录

88.合并两个有序数组
52.螺旋数组
567.字符串的排列
643.子数组最大平均数
150.逆波兰表达式
61.旋转链表
160.相交链表
83.删除排序链表中的重复元素
389.找不同
1491.去掉最低工资和最高工资后的工资平均值
896.单调序列
206.反转链表
92.反转链表II
141.环形链表
142.环型链表


目录

  • 系列目录
  • 389.找不同
    • 哈希表


389.找不同

🌟数组+哈希表/计数法

原题链接

方法一 哈希表
class Solution {
public:char findTheDifference(string s, string t) {vector<int> table(26, 0);for (auto& ch: s)table[ch - 'a'] ++;for (auto& ch: t) {table[ch - 'a'] --;if (table[ch - 'a'] < 0)return ch;}// 这里return -1;也是可以的// 字符串相关的题的错误指示符用——' '——较好// 也就是return ' ';return ' ';}
};

哈希表

简单介绍
一、种类:

1、存储结构:开放寻址法(更推荐)和拉链法

2、字符串哈希方式


二、主要作用:

将一个较大的空间或值域(通过一定的对应法则)映射到比较小的空间或值域

[ − 1 0 9 , 1 0 9 ] − > [ 1 0 5 , 0 ) [-10^9, 10^9] \quad->\quad[10^5, 0) [109,109]>[105,0)


三、一般的实现方式:

1、通过一个哈希函数h(x)映射

a. h(x)常用写法

对x取模运算,模上数组的长度N

h(x) = x mod N(这里的N一般取一个尽可能远离2的整数次幂的质数)

// 寻找合适长度 N的方法 
// 循环找到大于10w(1e5)的第一个整数
int main() {// 无上约束条件for (int i = 100000;; i ++) {bool flag = true;for (int j = 2; j * j <= i; j ++)if (i % j == 0) {flag = false;break;}if (flag) {cout << i << endl;break;}return 0;}
}

b. 哈希碰撞(哈希冲突)

eg. h(5) = 2; h(10) = 2;

​ 用拉链法处理哈希冲突

拉链法:开一个一维数组存储哈希值,并辅助一个单链表;


一起来看一道例题吧~

AcWing.840 模拟散列表

维护一个集合,支持如下几种操作:

I x,插入一个整数 x;
Q x,询问整数 x 是否在集合中出现过;
现在要进行 N 次操作,对于每个询问操作输出对应的结果

输入格式

第一行包含整数 N,表示操作数量

接下来 N 行,每行包含一个操作指令,操作指令为 I x,Q x 中的一种

输出格式

对于每个询问指令 Q x,输出一个询问结果,如果 x 在集合中出现过,则输出 Yes,否则输出 No

每个结果占一行

数据范围

1 ≤ N ≤ 105
−109 ≤ x ≤ 109

输入样例:

5
I 1
I 2
I 3
Q 2
Q 5

输出样例:

Yes
No
#include <bits/stdc++.h>using namespace std;// 通过上述方法或观察法
const int N = 100003;// e[] 表示当前节点的值;ne[] 表示下一个节点的地址
// idx 表示当前用到哪个位置
int h[N], e[N], ne[N], idx;// 插入x
void add(int x)
{int k = (x % N + N) % N;    	// 构造一个哈希函数,将x映射到[0,1e5)这个区间里e[idx] = x;ne[idx] = h[k];h[k] = idx ++;
}// 查询x是否存在
bool contain(int x)                // 查询操作是一个布尔类型的操作(返回true表示存在)
{	// 见注释int k = (x % N + N) % N;for (int i = h[k]; i != -1; i = ne[i])if (e[i] == x)return true;return false;               	// 否则返回false
}// 拉链法
int main()
{int n;scanf("%d", &n);memset(h, -1, sizeof h);    // 空指针一般用-1表示——将所有的槽清空while (n --) {char op[2];             // 若是用scanf的读入方式,尽量读入字符串scanf会自动过滤掉字符串中的回车、空格、制表符等int x;                  // 降低出错的概率(一般不用scanf读入字符)scanf("%s%d", op, &x);if (*op == 'I') add(x);      // 指针和整数比较出错;(禁止指针和整数进行比较)else {                       // 这里的*+指针(字符串)表示:(指针)op是一个指向char类型的指针变量if (contain(x)) puts("Yes");else puts("No");				}// else_end}// while_endreturn 0;  
}

注解:

(x % N + N) / N

  • C++中的模运算
    • 若x为负,则余数(运算结果)为负
    • 若x为证,则余数为正
  • +N的目的
    • 将余数(可能为负的)变为正数

memset(h, -1, sizeof h); // 空指针一般用-1表示——将所有的槽清空

初始化

scanf("%s%d", op, &x)

若使用scanf读入方式,应尽量读入字符串
读入字符串,scanf会自动过滤掉空格、回车、制表符等,降低出错的概率;
一般不用scanf读入字符

char *op

a.如果不加星号*
会报错:指针和整数比较出错;(禁止指针和整数进行比较)
b.这里的*+指针(字符串)表示:(指针)op是一个指向char类型的指针变量


四、基本操作(创建,销毁,增删 查——创销增删查)

添加——void add(int x)

删除——remove(int x)

​ 构造一个布尔类型的函数,在h(x)上打上标记,从逻辑上删除x(物理上并没有删除)

查找——bool contain(int x)

​ a.找到h(x)所在的槽

​ b.遍历这个槽存的值,以及对应的单链表,比较值是否相同,判断是否存在x



方法二 求和
class Solution {
public:char findTheDifference(string s, string t) {// accumulate of ..int as = 0, at = 0;for (auto ch: s)as += ch;for (auto ch: t)at += ch;return at - as;}
};



异或(XOR)运算

异或运算对任何给定的数字x 的性质,即x ^ x = 0x ^ 0 = x

LaTeX中,

\oplus 表示A和B的异或

\bigoplus 通常用于表示多个元素的异或

x ⊕ x = 0 x ⊕ 0 = x x\oplus x = 0\\x\oplus0=x xx=0x0=x

如果对两个相同的字符串进行异或,结果将是0;

如果再对结果和第三个字符串(即那个不同的字符)进行异或,结果将是那个不同的字符

此方法只适用于找出两个字符串之间的一个差异字符

方法三 异或运算 
// 类似方法二
class Solution {
public:char findTheDifference(string s, string t) {// 声明一个char变量,用来存最后的结果char res = 0;for (auto ch: s)res ^= ch;for (auto ch: t) res ^= ch;return res;}
};

这篇关于LeetCode:经典题之389 题解与延伸的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1089611

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

【JavaScript】LeetCode:16-20

文章目录 16 无重复字符的最长字串17 找到字符串中所有字母异位词18 和为K的子数组19 滑动窗口最大值20 最小覆盖字串 16 无重复字符的最长字串 滑动窗口 + 哈希表这里用哈希集合Set()实现。左指针i,右指针j,从头遍历数组,若j指针指向的元素不在set中,则加入该元素,否则更新结果res,删除集合中i指针指向的元素,进入下一轮循环。 /*** @param

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

HotSpot虚拟机的经典垃圾收集器

读《深入理解Java虚拟机》第三版笔记。 关系 Serial、ParNew、Parallel Scavenge、Parallel Old、Serial Old(MSC)、Concurrent Mark Sweep (CMS)、Garbage First(G1)收集器。 如图: 1、Serial 和 Serial Old 收集器 2、ParNew 收集器 3、Parallel Sc

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验