标签:
Given an array of integers, every element appears three timesexcept for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement itwithout using extra memory?
HideTags
#pragma once #include<iostream> #include<map> using namespace std; //法1:排序 //法2:STL容器map int singleNumber2(int A[], int n) { map<int, int> m; map<int, int>::iterator it; for (int i = 0; i < n; i++) { it = m.find(A[i]); if (it == m.end()) m[A[i]] = 1; else //m[A[i]]++; it->second++; } for (int i = 0; i < n; i++) if (m.at(A[i]) == 1)//at与find区别:at返回索引值对应的value,可能越界 return A[i]; } //法3:位运算。考虑全部用二进制表示,如果我们把 第 ith 个位置上所有数字的和对3取余,那么只 //会有两个结果 0 或 1 (根据题意,3个0或3个1相加余数都为0). 因此取余的结果就是那个 “Single Number”. int singleNumber3(int A[], int n) { //int四字节32位,每位和由一个数记录 int count[32] = { 0 };//每个元素都置0 int result = 0; for (int i = 0; i < 32; i++)//32位 { for (int j = 0; j < n; j++)//n个数 if (A[j] >> 1 & 1)//注意,操作只有一个&,判断才有俩 count[i]++; result |= ((count[i] % 3) << i);//好好体会。“|”:位或 } return result; } //法4:改进的位运算。 int singleNumber4(int A[], int n) { int ones = 0, twos = 0, threes = 0; for (int i = 0; i < n; i++) { //注意,每次循环前,ones twos threes互不相交 twos |= ones&A[i];//新2 = 原2不在A[i] + 原2在A[i] ones ^= A[i];//新1 = 原1不在A[i] + 原非1在A[i] //于是,新2 & 新1 = 原2在A[i]。即交集部分出现了3次,将交集部分在ones和twos中置0,ones twos就保证A[i]之后合理 threes = ones&twos;//注意threes意义并不是指A[i]后三次的位而是,这层循环中新产生的三次位 ones ^= threes;//ones &= ~threes;也行,但前者较快 twos ^= threes;//twos &= ~threes;也行,但前者较快 } return ones; } void main() { int A[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5 }; cout << singleNumber3(A, 13) << endl; system("pause"); }
137.Single Number II(法1排序法2STL容器map哈希法3位运算法4改进的位运算)
标签:
原文地址:http://blog.csdn.net/hgqqtql/article/details/43415711