一
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1] 输出: 1
示例 2:
输入: [4,1,2,1,2] 输出: 4
位运算。
一个数异或一个与他相同的数结果为0.
0异或一个数结果为这个数本身。
所以从头到尾将所有数异或一次,得到的结果就是那个只出现一次的数,其他数都抵消了。
class Solution
{
public:
int singleNumber(vector<int> &nums)
{
if(nums.size() == 1)
return nums[0];
int temp = nums[0];
for (int i = 1; i < nums.size(); i++)
{
temp = temp ^ nums[i];
}
return temp;
}
};
二
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3] 输出: 3
示例 2:
输入: [2,2,1,1,1,2,2] 输出: 2
方法一:
用内置容器map记录出现的次数。
class Solution
{
public:
int majorityElement(vector<int> &nums)
{
map<int, int> check;
for (int i = 0; i < nums.size(); i++)
{
check[nums[i]]++;
if(check[nums[i]] > nums.size() / 2)
{
return nums[i];
}
}
return 0;
}
};
方法二:
排序
class Solution
{
public:
int majorityElement(vector<int> &nums)
{
sort(nums.begin(), nums.end());
return nums[nums.size() / 2];
}
};
方法三:
摩尔投票法
class Solution
{
public:
int majorityElement(vector<int> &nums)
{
int temp = -1;
int count = 0;
for (int i = 0; i < nums.size(); i++)
{
if(count == 0)
{
temp = nums[i];
count = 1;
}
else
{
if(temp == nums[i])
{
count++;
}
else
{
count--;
}
}
}
return temp;
}
};
三
搜索二维矩阵 II
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
示例:
现有矩阵 matrix 如下:
[ [1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30] ]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
class Solution
{
public:
bool searchMatrix(vector<vector<int>> &matrix, int target)
{
int row = matrix.size();
if(row <= 0)
{
return false;
}
int col = matrix[0].size();
int i = 0, j = col - 1;
while(i >= 0 && i < row && j >= 0 && j < col)
{
if(matrix[i][j] > target)
{
j--;
}
else if(matrix[i][j] < target)
{
i++;
}
else
{
return true;
}
}
return false;
}
};
四
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 输出: [1,2,2,3,5,6]
原地算法,先把nums1中的元素移动到nums1数组的最后面。
class Solution
{
public:
void merge(vector<int> &nums1, int m, vector<int> &nums2, int n)
{
int size = nums1.size();
int i, j;
for (i = size - 1, j = m - 1; j >= 0; i--, j--)
{
nums1[i] = nums1[j];
}
i++, j++;
int k = 0;
while(i < size && j < n)
{
if(nums1[i] < nums2[j])
{
nums1[k++] = nums1[i++];
}
else
{
nums1[k++] = nums2[j++];
}
}
while(i < size)
{
nums1[k++] = nums1[i++];
}
while(j < n)
{
nums1[k++] = nums2[j++];
}
}
};