您的位置:首页 > 其它

算法总结(4)--Single Number相关问题

2016-10-12 16:37 246 查看
Single Number相关问题

主要涉及到位运算,和相关数学知识

===

二进制中1的个数

题目地址

http://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

求解

两个不同的数(表示成二进制时,肯定有一位是不同的)

n&(n-1) 可以让n最右边的二进制位为1变成0

ac代码

class Solution {
public:
int  NumberOf1(int n) {
int count = 0;
while(n!= 0){
count++;
n = n & (n - 1);
}
return count;
}
};


136. Single Number

题目地址

https://leetcode.com/problems/single-number/

题目描述

Given an array of integers, every element appears twice except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

只有一个数出现一次,其他数都出现两次

求解思路

亦或操作

* 1^0 = 1

* 0^1 = 1

* n^n = 0 (一个数与自己亦或等于0)

* 0^n = n (0与其他数亦或等于那个数)

ac代码

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


137. Single Number II

题目地址

https://leetcode.com/problems/single-number-ii/

题目描述

Given an array of integers, every element appears three times except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

只有一个数出现一次,其他数都出现三次

求解思路

或操作,0 | 0 = 0 ,其他等于1

一个int数 32位

每一位都与数组中的数相与,最后这一位上的1的个数为3次 加上唯一出现的那个数的该位,

利用这个思路求解

同理可以求解:只有一个数出现一次,其他数都出现k次的问题,上面的问题也可以采用此思路求解

ac代码

class Solution {
public:
int singleNumber(vector<int>& nums) {
int k = 3;
int len = nums.size();
int ans = 0;

int mask = 1; // int共32位
while (mask){

int cnt = 0;
for (int i = 0; i < len; i++)
{
if (nums[i] & mask) // 与上mask位 非零 就加上1
cnt++;
}

if (cnt % k == 1)
{
ans = ans | mask; //  或操作,使得改位置变成1
}

mask = mask << 1; // 左移动一位
}

return ans;
}
};


260. Single Number III

题目地址

https://leetcode.com/problems/single-number-iii/

题目描述

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:

* The order of the result is not important. So in the above example, [5, 3] is also correct.

* Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?

有两个只出现一次的数,其他数都出现2次

求解思路

这题借鉴136. Single Number

两个不同的数相与,二进制位肯定有一位是不同的,找到这样的一个位,然后与其他数相与,可以把数据分开成为两组,且每一组满足 136. Single Number的题目描述

ac代码如下

class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
int len = nums.size();

int rs = nums[0];
for (int i = 1; i < len; i++)
{
rs = rs^nums[i];
}

// rs中必有某一位为1,找到这一位 将数据分成两组,就能够得到最后结果
int findOne = 1;
while ((rs & findOne) == 0)
{
findOne = findOne << 1; // 左移1位
}

int rs1 = 0;
int rs2 = 0;

for (int i = 0; i < len; i++)
{
if ((nums[i] & findOne) == 0)
{
rs1 ^= nums[i];
}
else{
rs2 ^= nums[i];
}
}

vector<int> ans;
ans.push_back(rs1);
ans.push_back(rs2);
return ans;
}
};


268. Missing Number

题目地址

https://leetcode.com/problems/missing-number/

题目描述

Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.

For example,

Given nums = [0, 1, 3] return 2.

Note:

Your algorithm should run in linear runtime complexity. Could you implement it using onlyconstant extra space complexity?

求解思路

主要是需要用O(n)时间复杂度的算法

相关的视频讲解可以参考牛客网上左程云

ac代码

class Solution {
public:
int missingNumber(vector<int>& nums) {
int len = nums.size();

int le = 0; // 0到le-1已经有
int ri = len - 1; // le到ri想要有

while (le <= ri){
if (nums[le] == le){
le++;
}
else if (nums[le] < le || nums[le] > ri || nums[nums[le]] == nums[le]){
nums[le] = nums[ri]; //  ri要减小
ri--;
}
else{
int tmp = nums[nums[le]];
nums[nums[le]] = nums[le];
nums[le] = tmp;
}
}// end while

return le;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: