继续填坑,本篇文章带来的是leetcode初级算法数组篇6-11题的题解。
题目描述:给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。我们可以不考虑输出结果的顺序
算法说明:建立一个map索引,先遍历nums1数组,并把在map中存储nums1数组中每个元素的个数。然后遍历nums2数组,若该元素出现在map中的值大于0,则把该元素保存到结果中,并且在map中把该值减1。这样的话时间复杂度即扫描与查找,复杂度为O(nlogn),如果用hash map可以优化只O(n)。
实现的代码如下:
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
map<int,int> table;
vector<int> res;
for(int i=0;ifor(int i=0;iif(table[nums2[i]]>0) {res.push_back(nums2[i]);table[nums2[i]]--;}
return res;
}
};
题目描述:给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。你可以假设除了整数 0 之外,这个整数不会以零开头。
解题算法:一开始看这个题目看错了= =,wa了好多次,这题其实可以看成一个小加法模拟。解题思路就是给最后一位加一,然后判断会不会进位,然后在最高位的时候也要判断一次会不会在加一后等于10,如果是的话在数组前方再添加一位1。只是简单的模拟判断,时间复杂度为O(n)。
实现的代码如下:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
int c;
int temp;
temp=digits[digits.size()-1];
digits[digits.size()-1]=(digits[digits.size()-1]+1)%10;
c=(temp+1)/10;
for(int i=digits.size()-2;i>=0;i--){
temp=digits[i];
digits[i]=(digits[i]+c)%10;
c=(temp+c)/10;
}
if(c==1){
vector<int> res;
res.push_back(1);
for(int i=0;i<=digits.size()-1;i++)
res.push_back(digits[i]);
return res;
}
return digits;
}
};
题目描述:给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
解题算法:把不是0的数字放到前面,是0的最后加到数组后面就行了,时间复杂度O(n)。
代码:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int j=0;
for(int i=0;iif(nums[i]!=0) nums[j++]=nums[i];
for(int i=j;j0;
}
};
题目描述:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
算法说明:我一同学去腾讯面试被问到了原题= =,这题我的思路是这样的建立一个map索引,在扫描数组的时候以值为key,索引位置为value插入到map中,然后扫描的时候观察target减该值的key值是否在map中,在的话直接返回两个的索引即可,不在的话,加入map。时间复杂度最坏的情况下就是O(nlogn),同样可以使用hash map来优化。
代码:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> mp;
vector<int> res;
for(int i=0;imap<int,int>::iterator it;
for(int i=0;iif(it->second!=i&&it!=mp.end()) {
res.push_back(i);
res.push_back(it->second);
break;
}
}
return res;
}
};
题目描述:判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
数独部分空格内已填入了数字,空白格用 ‘.’ 表示。
示例 1:
输入:
[
[“5”,”3”,”.”,”.”,”7”,”.”,”.”,”.”,”.”],
[“6”,”.”,”.”,”1”,”9”,”5”,”.”,”.”,”.”],
[“.”,”9”,”8”,”.”,”.”,”.”,”.”,”6”,”.”],
[“8”,”.”,”.”,”.”,”6”,”.”,”.”,”.”,”3”],
[“4”,”.”,”.”,”8”,”.”,”3”,”.”,”.”,”1”],
[“7”,”.”,”.”,”.”,”2”,”.”,”.”,”.”,”6”],
[“.”,”6”,”.”,”.”,”.”,”.”,”2”,”8”,”.”],
[“.”,”.”,”.”,”4”,”1”,”9”,”.”,”.”,”5”],
[“.”,”.”,”.”,”.”,”8”,”.”,”.”,”7”,”9”]
]
输出: true
解题思路:一道细节题,就是判断横行每个区域的出现次数,所以建立三个数组表来存储即可,用于判断是不是满足每行每列每个区域只出现一次。那么对于n*n的的矩阵扫描一遍即可,时间复杂度为O(n^2)
其实现代码如下:
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
int rowtable[9][9]={0};
int columtable[9][9]={0};
int blocktable[9][9]={0};
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]!='.'){
char temp=board[i][j]-'1';
if((rowtable[i][temp]||columtable[j][temp]||blocktable[i/3*3+j/3][temp])==1) return false;
rowtable[i][temp]=columtable[j][temp]=blocktable[i/3*3+j/3][temp]=1;
}
}
}
return true;
}
};
题目描述:给定一个 n × n 的二维矩阵表示一个图像。将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
解题算法:因为要求是原地,即不使用额外的复杂度,所以在这个问题上我设置了一个temp,然后找出旋转时,其坐标对应的规律,然后按照题目的要求旋转即可,其代码如下:
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int temp;
int l=matrix.size();
for(int i=0;i2;i++)
for(int j=i;j1;j++){
temp=matrix[l-1-j][i];
matrix[l-1-j][i]=matrix[l-i-1][l-1-j];
matrix[l-i-1][l-j-1]=matrix[j][l-1-i];
matrix[j][l-1-i]=matrix[i][j];
matrix[i][j]=temp;
}
}
};
至此初级算法数组篇就全部结束了,之后会更新字符串篇等