26 从排序数组中删除重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
class Solution {
public int removeDuplicates(int[] nums) { //java
int index=0;
for(int i =1 ; i < nums.length ; i++){
if ( nums[i] != nums[index]){
index ++;
nums[index] = nums[i];
}
}
return ++index;
}
}
27 移除元素
原地移除所有=val的值,返回新数组的长度[3,2,2,3] 3 --> [2,2]
public int removeElement(int[] nums, int val) { //java
if(nums == null || nums.length == 0) return 0;
int index = 0;
for(int i = 0; i < nums.length; i++){
if(nums[i] != val){
nums[index] = nums[i];
index++;
}
}
return index;
}
mid 80 从排序数组中删除重复项II
/*
- 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。
*/
扩展 最多出现n次 repeat
int removeDuplicates(vector<int>& nums) { //c++
int repeatNum = 2;
int slow = repeatNum;
for (int fast = repeatNum; fast < nums.size(); fast++) {
if (nums[fast] != nums[slow-repeatNum]) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
mid-189旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
先将数组的前len-k个元素反转,后k个元素反转,然后再将整个数组反转。注意先让k对len取模。
java:
class Solution { //java
public void rotate(int[] nums, int k) {
int len = nums.length;
k = k%len;
if(len<2||k==0)return;
swap(nums, 0, len-k-1);
swap(nums, len-k, len-1);
swap(nums, 0, len-1);
}
public void swap(int[] nums, int left, int right){
while(left<right){
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++;
right--;
}
}
}
136 只出现一次的数字 位运算
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
异或,出现偶数次的元素会被清零,于是留下来的就是那个只出现一次的数字。
public int singleNumber(int[] nums) { //java
int res = 0;
for(int i = 0; i < nums.length; i++){
res = res ^ nums[i];
}
return res;
}
mid-137 只出现一次的数字II
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
方法1:map
int singleNumber(vector<int>& nums) { //c++
map<int,int> mymap; // key:num value:cnt
map<int,int>::iterator it;
for (int i = 0; i < nums.size(); i++) {
it = mymap.find(nums[i]);
if (it != mymap.end()) {
it->second ++;
} else {
mymap.insert(map<int,int>::value_type(nums[i], 1));
}
}
it = mymap.begin();
while (it != mymap.end()) {
if (it->second == 1) {
return it->first;
}
it++;
}
return 0;
}
C++ map用法:
c++map基础用法
mid-260 只出现一次的数字III 多个出现一次
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
vector<int> singleNumber(vector<int>& nums) { //c++
map<int, int> mymap;
map<int, int>::iterator it;
for (int i = 0; i < nums.size(); i++) {
it = mymap.find(nums[i]);
if (it != mymap.end()) {
it->second++;
} else {
mymap.insert(pair<int, int>(nums[i], 1));
}
}
vector<int> res;
it = mymap.begin();
while (it != mymap.end()) {
if (it->second == 1) {
res.push_back(it->first);
}
it++;
}
return res;
}
349两个数组的交集
要求输出元素唯一,即去重
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
c++
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { //c++
vector<int> res;
int p1 = 0;
int p2 = 0;
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
while (p1 < nums1.size() && p2 < nums2.size()) {
if(nums1[p1] == nums2[p2]) {
res.push_back(nums1[p1]);
p1++;
p2++;
while (p1 < nums1.size() && nums1[p1]==nums1[p1-1]) p1++; //去重
while (p2 < nums2.size() && nums2[p2]==nums2[p2-1]) p2++;
continue;
} else if(nums1[p1] < nums2[p2]) {
p1++;
} else{
p2++;
}
}
return res;
}
mid-350 数组交集II
不去重即可
66加一
给定一个非负整数组成的非空数组,在该数的基础上加一,返回一个新的数组。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
注意进位的处理。
class Solution { // Java
public int[] plusOne(int[] digits) {
int len = digits.length;
if(len==0)return new int[0];
int[] res = new int[len+1];
res[len] = (digits[len-1]+1)%10;
int carry = (digits[len-1]+1)/10;
for(int i=len-2;i>=0;i--){
res[i+1] = (digits[i]+carry)%10;
carry = (digits[i]+carry)/10;
}
res[0] = carry;
if(carry!=0)return res;
int[] res1 = new int[len];
System.arraycopy(res, 1, res1, 0, len);
return res1;
}
}
283移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
class Solution { //java
public void moveZeroes(int[] nums) {
int len = nums.length;
if(len<2)return;
int index = 0;
for(int i=0;i<len;i++){
if(nums[i]!=0)nums[index++] = nums[i];
}
for(int i=index;i<len;i++)nums[i] = 0;
}
}
mid-36 有效的数独
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
- 数字 1-9 在每一行只能出现一次。
- 数字 1-9 在每一列只能出现一次。
- 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
使用一个二维数组seat保存所有数字的位置,遍历输入的数独,遇见数字则先判断该位置是否与seat中相同数字的位置冲突,若冲突则返回false,否则将当前数字的位置保存至seat中。
java:
class Solution { //java
public boolean isValidSudoku(char[][] board) {
boolean[][] seat=new boolean[9][27];
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(board[i][j]=='.')continue;
int num=board[i][j]-'0';
int grid=(i/3)*3+(j/3);
if(seat[num-1][i]||seat[num-1][j+9]||seat[num-1][grid+18])return false;
else{
seat[num-1][i]=true;
seat[num-1][j+9]=true;
seat[num-1][grid+18]=true;
}
}
}
return true;
}
}
c++二维数组初始化:
vector<vector<int>> row(9, vector<int>(10,0));
mid 48-旋转图像
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
你必须在原地旋转图像。
先按主对角线翻转,再按垂直对称轴翻转。或者,先水平翻转,后主对角线翻转。
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i >= j) continue;
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}
// 左右
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j >= n/2) continue;
int tmp = matrix[i][j];
matrix[i][j] = matrix[i][n-j-1];
matrix[i][n-j-1] = tmp;
}
}
return;
}
mid 49 字母异位词分组
按字母异位词组合输出,所有源单词中的字母通常只使用一次
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
bool countEqual(int i, int j, vector<vector<int>> &count) {
for (int m = 0; m < 26; m++) {
if (count[i][m] != count[j][m]) return false;
}
return true;
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
int size = strs.size();
vector<vector<int>> count(size, vector<int>(26,0));
for (int i = 0; i < size; i++) {
for (int j = 0; j < strs[i].size(); j++) {
count[i][strs[i].at(j)-'a'] += 1;
}
}
vector<vector<string>> res;
vector<bool> flag(size,0);
for (int i = 0; i < strs.size(); i++) {
if (flag[i]) continue;
vector<string> subres;
flag[i] = true;
subres.push_back(strs[i]);
for (int j = i; j < strs.size(); j++) {
if (flag[j]) continue;
if (countEqual(i, j, count)) {
flag[j] = true;
subres.push_back(strs[j]);
}
}
res.push_back(subres);
}
return res;
}
vector排序
2418 按身高排序(自定义cmp)
输入:names = [“Mary”,“John”,“Emma”], heights = [180,165,170]
输出:[“Mary”,“Emma”,“John”] 解释:Mary 最高,接着是 Emma 和 John 。
按身高降序输出name
#include <vector>
#include <string>
#include "algorithm"
using namespace std;
class Solution {
struct People {
string name;
int height;
};
static bool cmp(const People &p1, const People &p2) {
return p1.height > p2.height;
}
public:
vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
vector<People> pe;
for (int i = 0; i < names.size(); i++) {
People p = {
.name = names[i],
.height = heights[i],
};
pe.push_back(p);
}
sort(pe.begin(), pe.end(), cmp);
vector<string> res;
for (int i = 0; i < names.size(); i++) {
res.push_back(pe[i].name);
}
return res;
}
};
mid-406 根据身高重建队列 (自定义cmp)
输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
步骤一:第一个元素降序,第二个元素升序
步骤二:遍历插入,将数组对的第二个元素值作为插入目标index
#include <vector>
#include "algorithm"
using namespace std;
class Solution {
static bool cmp(const vector<int> &a, const vector<int> &b) {
if(a[0] == b[0]) return a[1] < b[1];
return a[0] > b[0];
}
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp);
vector<vector<int>> res;
for(int i = 0; i < people.size(); i++) {
res.insert(res.begin()+people[i][1], people[i]);
}
return res;
}
};