BZOJ 2011 不重复的数字 哈希 or set or 二叉搜索树

这是我第一次写哈希,感觉还好。虽然这道题今天一直在想用什么方法最好,一开始想过用 unique 这个函数, 想过 map ,想过 set,(刚才看别人题解的过程中,也有用treap写的,其实就是二叉搜索树) 但是map 和 set 查询都是 log n的,太慢了点。而且,我一直想学哈希,之所以一直没怎么学(只看了理论,没写过),有一个原因也是看过的哈希的代码太少(印象中只有紫书中的一篇和下文代码类似的,还有白书中基于哈希值的LCP),自己不好把握(这一次写,第一次交,就因为负数的问题,RE),最后就把他拿来做为 哈希 的第一道题了,加油,这是我朝哈希迈出的第一步。

这是set的代码,一开始我还不知道set中怎么查询有没有一个值的存在。最后百度了才知道,唉,要加油啊!傻逼!(这份代码跑了700多毫秒)

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<set>
 4 #define rep(i,j,k) for(int i = j; i <= k; i++)
 5 #define maxn 50005
 6 using namespace std;
 7
 8 set<int> s;
 9 int read()
10 {
11     int s = 0, t = 1; char c = getchar();
12     while( !isdigit(c) ){
13         if( c == ‘-‘ ) t = -1; c = getchar();
14     }
15     while( isdigit(c) ){
16         s = s * 10 + c - ‘0‘; c = getchar();
17     }
18     return s * t;
19 }
20
21 int main()
22 {
23     int t = read();
24     while( t-- ){
25         s.clear();
26         int n = read();
27         bool first = 1;
28         rep(i,1,n){
29             int x = read();
30             if( !s.count(x) ){
31                 if( first ) {
32                     printf("%d", x);
33                     first = 0;
34                 }
35                 else printf(" %d", x);
36                 s.insert(x);
37             }
38         }
39         printf("\n");
40     }
41     return 0;
42 }

这是哈希的代码,只跑了480毫秒

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define rep(i,j,k) for(int i = j; i <= k; i++)
 5 #define maxn 100003
 6 #define mod 100003
 7 using namespace std;
 8
 9 int head[maxn] = {0}, next[maxn] = {0};
10 int num[maxn] = {0};
11
12 int read()
13 {
14     int s = 0, t = 1; char c = getchar();
15     while( !isdigit(c) ){
16         if( c == ‘-‘ ) t = -1; c = getchar();
17     }
18     while( isdigit(c) ){
19         s = s * 10 + c - ‘0‘; c = getchar();
20     }
21     return s * t;
22 }
23
24 int try_to_insert(int s)
25 {
26     int h = num[s] % mod;  if( h < 0 ) h = -h;
27     int u = head[h];
28     while( u ){
29         if( num[u] == num[s] ) return 0;
30         u = next[u];
31     }
32     next[s] = head[h];
33     head[h] = s;
34     return 1;
35 }
36
37 int main()
38 {
39     int t = read();
40     while( t-- ){
41         memset(head,0,sizeof(head));
42         int n = read();
43         bool first = 1;
44         rep(i,1,n){
45             num[i] = read();
46             if( try_to_insert(i) ){
47                 if( first ) {
48                     printf("%d", num[i]);
49                     first = 0;
50                 }
51                 else printf(" %d", num[i]);
52             }
53         }
54         printf("\n");
55     }
56     return 0;
57 }
时间: 2024-10-29 22:22:15

BZOJ 2011 不重复的数字 哈希 or set or 二叉搜索树的相关文章

BZOJ 2761 不重复数字 (Hash)

题解:直接使用STL中的hash去重即可 #include <cstdio> #include <map> using namespace std; int ans[50010]; int main(){ int T,n,tmp; scanf("%d",&T); while(T--){ int cnt=0; map<int,int>m; scanf("%d",&n); for(int i=0;i<n;i++)

查找数组中重复的数字

题目来源于<剑指Offer>中的面试题3:找出数组中重复的数字. // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次.请找出数组中任意一个重复的数字.例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3}, // 那么对应的输出是重复的数字2或者3. 解决方法有多种,包括数组排序,哈希表法,以及作者推荐的重排数组法.此处介绍自己的一个做法,以空间换时间,通过新建数组来实现快速查

(剑指Offer)面试题51:数组中重复的数字

题目: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 思路: 1.排序 将数组排序,然后扫描排序后的数组即可. 时间复杂度:O(nlogn),空间复杂度:O(1) 2.哈希表 从头到尾扫描数组,每扫描到一个数字,判断该数字是否在哈希表中,如果该哈希表还没有这个数字,那么加入哈希

剑指Offer面试题51(Java版):数组中重复的数字

题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复的次数.请找出数组中任意一个重复的数字. 例如如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3. 解决这个问题的一个简单的方法是先把输入的数组排序.从排序的数组中找出重复的数字是件容易的事情,只需要从头到尾扫描排序后的数组就可以了.排序一个长度为n的数组需要时间为O(nlogn)时间. 还可以利用哈希表来解决这个问题,从头到尾

49 数组中重复的数字 记忆

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2. 思路:1)直接排序: 2)使用哈希表,比如开辟一个布尔数组,判断该数字在之前是否已经访问过,vector<bool> visit(n,false);已经访问过,则找到这个重复数字. 3)时间复杂度是O(n),空间复杂度是

数组中找到重复的数字

1.要求从一个数组中获取最小的重复的数字,乱序数组,给定范围:长度n,大小0~n-1 class solution { public: bool findDuplicate(int nums[],int length,int *p) { if(nums == nullptr) { cout<<"数组不存在,请检查"<<endl; return false; } for(int i=0; i<length; i++) if(nums[i]<0 || n

剑指offer:数组中重复的数字

题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2. # -*- coding: utf-8 -*- # @Time : 2019-04-15 17:31 # @Author : Jayce Wong # @ProjectName : job # @FileName : du

一起来刷《剑指Offer》——不修改数组找出重复的数字(思路及Python实现)

数组中重复的数字 在上一篇博客中<剑指Offer>-- 题目一:找出数组中重复的数字(Python多种方法实现)中,其实能发现这类题目的关键就是一边遍历数组一边查满足条件的元素. 然后我们在博客用最复杂的方式学会数组(Python实现动态数组)这篇博客中介绍了数组这一结构的本质,并自己动手实现了一个动态数组. 今天我们介绍一下另一道来自<剑指Offer>的关于数组的面试题--不修改数组找出重复的数字. 不修改数组找出重复的数字 题目二:不修改数组找出重复的数字 给定一个长度为 n+

【剑指offer】09-数组中重复的数字

题目: 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2. 思路: 1.因为所有数字都在0-n-1范围内,将所有数排好序,若前一个数等于后一个数,就返回true class Solution: # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] # 函数返回T