这些题目首先都是未排序的
1、 136 single number
在数组中所有数字都出现两次,只有一个数字出现一次,求出这个数。
思路1:使用位运算,两个相同的数异或为0。
时间复杂度 n
思路2:建立一个哈希表,出现了就计入,再次出现就减去,最后寻找只出现一次的那个数。 nlogn,需要额外空间
class Solution {
public:
int singleNumber(vector<int>& nums) {
set<int> res;
for(auto n:nums)
{
if(res.find(n)!=res.end()) res.erase(n);
else res.insert(n);
}
return *res.begin();
}
};
2、268. 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
.
找到仅有的缺失的数
思路1:使用抑或将数字和标号抑或,最后再跟size抑或,最后剩下的就是缺失的数
思路2:排序,求差值(不好)
3 41. First Missing Positive
Given an unsorted integer array, find the first missing positive integer.
For example,
Given [1,2,0]
return 3
,
and [3,4,-1,1]
return 2
.
Your algorithm should run in O(n) time and uses constant space.
思路:本来正确的数列,有一个数被代替了(可能被0或者负数代替),这样,将每一个在1-n范围的数都排回去,那么丢失的那个数上一定是替代的那个数class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n=nums.size();
for(int i=0;i<n;i++)//桶排序
{
while(nums[i]>0&&nums[i]<=n&&nums[i]!=i+1&&nums[i]!=nums[nums[i]-1])//不加最后一个判断,会进入死循环,因为重复的数字可能在n范围之内
swap(nums[i],nums[nums[i]-1]);
}
for(int i=0;i<n;i++)
{
if(nums[i]!=i+1)
return i+1;
}
return n+1;
}
};
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input: [4,3,2,7,8,2,3,1] Output: [5,6]思路1:将当前的数和它应该在的位置交换,直到有了应该是这个位置的数,如果出现与交换的位置相同的数,那么这个数就是一个重复值。转到下一个数,遍历一遍,后在遍历一遍,看与标号不相等的数,把标号写入输出即可。
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int i=0;
while(i<nums.size())
{
if(nums[i]!=nums[nums[i]-1]) swap(nums[i],nums[nums[i]-1]);
else i++;
}
vector<int> res;
for(int i=0;i<nums.size();i++)
{
if(nums[i]!=i+1) res.push_back(i+1);
}
return res;
}
};
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
int len = nums.size();
for(int i=0; i<len; i++) {
int m = abs(nums[i])-1; // index start from 0
nums[m] = nums[m]>0 ? -nums[m] : nums[m];
}
vector<int> res;
for(int i = 0; i<len; i++) {
if(nums[i] > 0) res.push_back(i+1);
}
return res;
}
};
Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements that appear twice in this array.
Could you do it without extra space and in O(n) runtime?
Example:
Input: [4,3,2,7,8,2,3,1] Output: [2,3]与上一题基本一样
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int i=0;
while(i<nums.size())
{
if(nums[i]!=nums[nums[i]-1]) swap(nums[i],nums[nums[i]-1]);
else i++;
}
vector<int> res;
for(int i=0;i<nums.size();i++)
{
if(nums[i]!=i+1) res.push_back(nums[i]);
}
return res;
}
};
public class Solution { // when find a number i, flip the number at position i-1 to negative. // if the number at position i-1 is already negative, i is the number that occurs twice. public List<Integer> findDuplicates(int[] nums) { List<Integer> res = new ArrayList<>(); for (int i = 0; i < nums.length; ++i) { int index = Math.abs(nums[i])-1; if (nums[index] < 0) res.add(Math.abs(index+1)); nums[index] = -nums[index]; } return res; } }
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than
O(n2)
. - There is only one duplicate number in the array, but it could be repeated more than once.
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n=nums.size();
int slow=nums[0];
int fast=nums[slow];
if(nums.size()<=1) return -1;
while(slow!=fast)
{
slow=nums[slow];
fast=nums[nums[fast]];
}
fast=0;
while(slow!=fast)
{
slow=nums[slow];
fast=nums[fast];
}
return slow;
}
};