注:以下代码均为c++
1. 删除排序数组中的重复项
思想:快慢指针
int removeDuplicates(vector<int>& nums) {
if(nums.size() == 1) return 1;
int quick, slow;
for(slow = 0, quick = 1; quick < nums.size(); quick++){
if(nums[quick] != nums[slow])
nums[++slow] = nums[quick];
}
return slow + 1;
}
直接用unique函数
int removeDuplicates(vector<int>& nums) {
auto u = unique(nums.begin(), nums.end()); // unique将相邻的重复元素移到向量的末尾,并返回一个指向第一个重复元素的迭代器。
auto ans = u - nums.begin();
return ans;
}
2. 旋转数组
void rotate(vector<int>& nums, int k) {
int i, j, t;
k = k % nums.size();
if(k != 0){
// 1. 反转整个数组
for(i = 0, j = nums.size() - 1; i < j; i++, j--){
t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
// 2. 反转前k项
for(i = 0, j = k - 1; i < j; i++, j--){
t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
// 3. 反转后面的
for(i = k, j = nums.size() - 1; i < j; i++, j--){
t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
}
3. 存在重复元素
bool containsDuplicate(vector<int>& nums) {
int i;
sort(nums.begin(), nums.end());
for(i = 0; i < nums.size() - 1; i++){
if(nums[i] == nums[i + 1])
return true;
}
return false;
}
4. 只出现一次的数字
思路:先排序,再一次遍历
int singleNumber(vector<int>& nums){
int n = nums.size();
if(n == 1) return nums[0];
sort(nums.begin(), nums.end());
for(int i = 0; i < n - 1; i = i + 2){
if(nums[i] != nums[i+1])
return nums[i];
}
return nums[n-1];
}
5. 两个数组交集2
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
int i = 0, j = 0;
vector<int> result;
while(i < nums1.size() && j < nums2.size()){
if(nums1[i] > nums2[j])
j++;
else if(nums1[i] < nums2[j])
i++;
else{
result.push_back(nums1[i]);
i++;
j++;
}
}
return result;
}
6. 加一
vector<int> plusOne(vector<int>& digits) {
int n = digits.size(), i;
for(i = n - 1; i >= 0; i--){
if(digits[i] != 9) {
digits[i]++;
return digits;
}
else
digits[i] = 0;
}
digits.resize(n + 1);
digits[0] = 1;
return digits;
}
7. 移动零
思想:双指针
void moveZeroes(vector<int>& nums) {
int i = 0, j = 0;
for(j = 0; j < nums.size(); j++){
if(nums[j] != 0){
nums[i] = nums[j];
i++;
}
}
for(;i < nums.size(); i++)
nums[i] = 0;
}
8. 两数之和
思路:
定义一个哈希表,第一行存数,第二行存其索引。
遍历数组,一边查表一边写表。
#include <unordered_map>
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable; //定义哈希表,第一行存nums,第二行存其索引。
int n = nums.size();
//遍历数组
for(int i = 0; i < n; i++){
auto it = hashtable.find(target - nums[i]); //查哈希表,找当前元素对应的另一个元素
if(it != hashtable.end()) //如果当前元素对应的另一个元素在哈希表里,返回这两个元素的索引。
return {it->second, i};
hashtable[nums[i]] = i; //写哈希表
}
return {};
}
9. 有效数独
bool isValidSudoku(vector<vector<char>>& board) {
int rows[9][9]; //每一行1~9出现的次数
int columns[9][9]; //每一列1~9出现的次数
int subboxes[3][3][9]; //每个方块1~9出现的次数
int i, j;
//遍历整个棋盘,将出现过的数记录下来,若出现次数超过1,则返回false
for(i = 0; i < 9; i++){
for(j = 0; j < 9; j++){
char c = board[i][j];
if(c != '.'){
int index = c - '0' - 1; //因为数独范围为1-9,数组范围为0-8
rows[i][index]++;
columns[j][index]++;
subboxes[i/3][j/3][index]++;
if(rows[i][index] > 1 || columns[j][index] > 1 || subboxes[i/3][j/3][index] > 1)
return false;
}
}
}
//否则返回true
return true;
}