开始之前:
只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
思路:
题目中明确表明其余元素出现两次,可以考虑异或操作(相同为0,不同为1,最终输出只出现一次的元素)
程序代码:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int num=0;
for(int i=0;i<nums.size();i++)
num^=nums[i]; //vector中每个元素与num异或
return num;
}
};
求众数
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
思路1:
直观思路就是,排序,然后找其中下标为N/2的元素(题目中说众数是指在数组中出现次数大于n/2
的元素,那下标为N/2的元素必然为众数)
程序代码:
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end()); //排序
return nums[nums.size()/2];
}
};
思路2:
另一个思路就是,通过计数来确定,从第一个数开始,相等则num+1,不等则num-1,减至0则将下一个数用来比较;
程序代码:
class Solution {
public:
int majorityElement(vector<int>& nums) {
int num=1; //初始元素至少数目有一个
int maj=nums[0]; //一开始定位第一个元素
for(int i=1;i<nums.size();i++)
if(maj==nums[i]) //相等则+1
num=num+1;
else{
num=num-1; //不等则-1
if(num==0) //当前数目为0,将maj置为下一个元素(前面打平手,没有占优势,相当于比拼打平手之后的元素)
maj=nums[i+1];
}
return maj;
}
};
搜索二维矩阵 II
编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
- 每行的元素从左到右升序排列。
- 每列的元素从上到下升序排列。
思路:
直观想法是遍历整个数组,但是题目中的高效二字限定了不能使用那种方法;
矩阵是按照行列升序排列,因此可以角向中间运动的方式,这里选用从右上角开始,矩阵的值小于目标值则需要行+1,大于目标值则需要列-1
程序代码:
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.size()==0)
return false;
int i=0; //行
int j=matrix[0].size()-1; //列
//从右上角开始
while(j>=0&&i<matrix.size()){
if(matrix[i][j]==target)
return true;
if(matrix[i][j]<target)
++i;
else
--j;
}
return false;
}
};
合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
- 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
- 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素
思路1:
将nums2直接插到nums1的后面,然后排序;
程序代码:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
for(int i=m;i<m+n;i++)
nums1[i]=nums2[i-m];
sort(nums1.begin(),nums1.end());
}
};
思路2:
考虑nums1的长度为m+n,可以考虑不重新构建数组,直接找nums1中操作
程序代码:
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int k=m-- +n-- -1;
while(m>=0&&n>=0){
if(nums1[m]<nums2[n]){ //如果nums2末端的元素大于nums1的,
nums1[k]=nums2[n]; //就将其放在nums1最末端
k--;
n--;
}else{
nums1[k]=nums1[m]; //如果nums1末端的元素大于nums2的,
k--; //就将其放在nums1最末端
m--;
}
}
while(n>=0){ //nums2的元素没有放完,则全部从后往前放入nums1
nums1[k]=nums2[n];
k--;
n--;
}
}
};