leetcode 数组类型题总结
1,removeDuplicates(I)
int removeDuplicatesI(vector<int>& nums){ // 重新组织数组,同 removeDuplicates2IV
int index = ;
for(int i=;i<nums.size();++i){
if(i> && nums[i] == nums[i-])
continue;
nums[index++] = nums[i];
}
return index;
}
int removeDuplicatesII(vector<int>& nums) { // 数组覆盖操作
if(nums.empty()) return ;
int index = ;
for(int i=;i<nums.size();++i) {
if(nums[i-] != nums[i])
nums[index++] = nums[i];
}
return index;
}
int removeDuplicatesIII(vector<int>& nums) { // STL::hashmap
map<int,int> mapping;
if(nums.empty()) return ;
for(int i=;i<nums.size();++i) {
if(mapping.find(nums[i]) != mapping.end())
mapping[nums[i]] += ;
else
mapping[nums[i]] = ;
}
return mapping.size();
}
int removeDuplicatesIV(vector<int>& nums) { // STL::set
set<int> myset;
for(int i=;i<nums.size();++i)
myset.insert(nums[i]);
return myset.size();
}
int removeDuplicatesV(vector<int>& nums) { // STL::unique,STL::distance
return distance(nums.begin(),unique(nums.begin(),nums.end()));
}
removeDuplicates(I)
removeDuplicates(II)
int removeDuplicates2I(vector<int>& nums) { // STL::haspmap
map<int,int> mapping;
for(int i=;i<nums.size();++i) {
if(mapping.find(nums[i]) != mapping.end()){
if(mapping.find(nums[i])->second == )
mapping.find(nums[i])->second = ;
else
mapping.find(nums[i])->second += ;
}
else
mapping[nums[i]] = ;
}
int result=;
for(map<int,int>::iterator it = mapping.begin();it != mapping.end();++it) {
result += it->second;
}
return result;
}
int removeDuplicates2II(vector<int>& nums) { // 思路同 removeDuplicatesII,覆盖操作,扩展性好
if(nums.size()<) return nums.size();
int index = ; // index表示将要覆盖的三个相同元素的最后一个元素位置
for(int i=;i<nums.size();++i) {
if(nums[i] != nums[index-])
nums[index++] = nums[i]; // 覆盖三个相同元素的最后一个
}
return index;
}
int removeDuplicates2III(vector<int>& nums) { // STL::erase 函数
if(nums.size()<) return nums.size();
for(vector<int>::iterator it=nums.begin();it!=nums.end()-;++it)
if(*it == *(it + ) && *it == *(it + ))
it = nums.erase(it);
return nums.size();
}
int removeDuplicates2IV(vector<int>& nums) { // 重新组织数组
int index = ; // index 表示下次放元素的位置
for(int i=;i<nums.size();++i){
if(i> && i<nums.size()- && nums[i]==nums[i-] && nums[i]==nums[i+])
continue; // 和左右两边相等的元素跳过(不放入重组数组中)
nums[index++] = nums[i];
}
return index;
}
removeDuplicates(II)
2, search(I)
int search1(const vector<int>& nums,int target) {
int first = ;
int last = nums.size()-;
while(first <= last) {
int mid = first + (last - first)/;
if(nums[mid]==target)
return mid;
else if(nums[first]<=nums[mid]) { // mid在左半部分
if(nums[first]<=target && target<nums[mid])
last = mid - ;
else
first = mid + ;
}
else { // mid在右半部分
if(nums[mid]<target && target<=nums[last])
first = mid + ;
else
last = mid - ;
}
}
return -;
}
search(I)
search(II)
int search2(const vector<int>& nums,int target) {
int first = ;
int last = nums.size()-;
while(first <= last) {
int mid = first + (last - first)/;
if(nums[mid]==target)
return mid; if(nums[first]<=nums[mid]) { // mid 在左半部分
if(nums[first]<nums[mid]) { // nums[first] < nums[mid]
if(nums[first]<=target && target<nums[mid])
last = mid - ;
else
first = mid + ;
}
else // nums[first] == nums[mid]
first++; // 缩短查找区间
}
else { // nums[first] > nums[mid],mid 在右半部分
if(nums[mid]<target && target<=nums[last])
first = mid +;
else
last = mid - ;
}
}
return -;
}
search(II)
3,连续序列长度
int longestConsecutive(const vector<int>& nums) {
map<int,bool> mapping;
if(nums.empty()) return ;
int longestLengths = ;
for(int i=;i<nums.size();++i) {
mapping[nums[i]] = false; // 用来表示该元素是否用过,因为同一连续序列的元素的连续序列长度相同,无序再计算
} for(int i=;i<nums.size();++i) {
int Lengths = ;
if(mapping[nums[i]]) continue;
for(int j = ;;++j) { // 从右边往左边找
map<int,bool>::iterator it = mapping.find(nums[i]-j);
if(it != mapping.end()){
Lengths++;
it->second = true;
}
else
break;
}
for(int j=;;++j) { // 从左往右找
map<int,bool>::iterator it = mapping.find(nums[i]+j);
if(it != mapping.end()) {
Lengths++;
it->second = true;
}
else
break;
}
longestLengths = max(longestLengths,Lengths);
}
return longestLengths;
}
longestConsecutive
4, 查询两个有序数组的第 K 个元素
int findMedianSortedArray(const vector<int>& A,const vector<int>& B) {
vector<int> result;
result.reserve(A.size()+B.size());
merge(A.begin(),A.end(),B.begin(),B.end(),result.begin());
return result[result.size()/]; }
findMedianSortedArray
5,twoSum
vector<int> twoSum1(vector<int>& nums,int target) { // STL::hashmap
map<int,int> mapping;
vector<int> result;
for(int i=;i<nums.size();++i)
mapping[nums[i]] = i;
for(int i=;i<nums.size();++i){
if(mapping.find(target-nums[i])!=mapping.end() && mapping[target-nums[i]]>i){
result.push_back(i+);
result.push_back(target-nums[i]+);
break;
}
return result;
}
} vector<int> twoSum2(vector<int>& nums,int target) { // 先排序,再左右夹逼
vector<int> result;
int first = ; // 保存元素下标
int last = nums.size()-;
sort(nums.begin(),nums.end());
while(first<last) {
if(nums[first] + nums[last] == target){
result.push_back(first+);
result.push_back(last+);
break;
}
if(nums[first] + nums[last] > target) {
last--;
}
else {
first++;
}
}
return result;
}
twoSum
6, threeSum
vector<vector<int> > threeSumI(vector<int>& nums) { //跳过重复的数
vector<vector<int> > result;
const int target = ;
vector<int>::iterator it;
for(it=nums.begin();it<nums.end()-;++it) { // 遍历第一个数,剩余两个数进行夹逼
vector<int>::iterator j=it+;
vector<int>::iterator k=nums.end()-;
if(it!=nums.begin() && *it == *(it-)) continue;
while(j < k) {
if(*it + *j + *k == target){
result.push_back({*it,*j,*k});
++j;
--k;
while(*j == *(j-) && *k = *(k+) && j < k) ++j; // 跳过重复的数
}
else if(*it + *j + *k < target){
++j;
while(*j == *(j-) && j < k) ++j; // 跳过重复
}
else {
--k;
while(*k = *(k+) && j < k) --k; // 跳过重复
}
}
}
return result;
} vector<vector<int>> threeSumII(vector<int>& nums) { //不跳过重复的数 ,最后直接去重
vector<vector<int>> result;
const int target = ;
vector<int>::iterator it;
for(it=nums.begin();it<nums.end()-;++it) {
vector<int>::iterator j=it+;
vector<int>::iterator k=nums.end()-;
if(it!=nums.begin() && *it == *(it-)) continue;
while(j < k) {
if(*it + *j + *k == target){
result.push_back({*it,*j,*k});
++j;
--k;
}
else if(*it + *j + *k < target){
++j;
}
else {
--k;
}
}
}
sort(result.begin(),result.end(),less<int>()); // 去重
result.erase(unique(result.begin(),result.end()),result.end());
return result;
} vector<vector<int>> threeSumIII(vector<int>& nums) { // STL::hashmap
vector<vector<int>> result;
map<int,vector<pair<int,int>>> cache;
const int target = ;
if(nums.size()<) return result;
sort(nums.begin(),nums.end());
for(int i=;i<nums.size();++i){
for(int j=i+;j<nums.size();++j) {
cache[nums[i]+nums[j]].push_back(make_pair(i,j));
}
}
for(int i=;i<nums.size();++i) {
const int key = target - nums[i];
if(cache.find(key)==cache.end()) continue; for(int j=;j<cache[key].size();++j) {
if(i<=cache[key].second) //不会出现 [1,2,3],[1,3,2] [2,1,3]都被加入的情况,如果这行不写,最后需要对每个新加入的 vector 排序,然后加入,最后判重。
continue;
vector<pair<int,int>>& vec = cache[key];
result.push_back({nums[vec[i].first],nums[vec[i].second],nums[i]});
}
}
sort(result.begin(),result.end()); // 可能有重复值,必须去重!比如:nums=[0,0,0,0,0,0],target=0
result.erase(unique(result.begin(),result.end()),result.end());
return result;
}
threeSum
7, threeSumClose
int threeSumClose(vector<int>& nums,int target) {
int result = ;
int minGap = INT_MAX;
sort(nums.begin(),nums.end());
for(int i=;i<nums.size()-;++i) {
int j=i+;
int k=nums.size()-;
while(j<k) {
int sum = nums[i]+nums[j]+nums[k];
int gap = abs(target-sum);
if(gap<minGap) {
result = sum;
minGap = gap;
}
if(sum<target) ++j;
else --k;
}
}
return result;
}
threeSumClose
8, fourSum
vector<vector<int>> fourSum(vector<int>& nums,int target) { //先排序,在两边夹逼
vector<vector<int>> result;
if(nums.size()<) return result;
sort(nums.begin(),nums.end());
for(int a=;a<nums.size()-;++a) {
for(int b=a+;b<nums.size()-;++b) {
int c=b+;
int d=nums.size()-;
while(c < d) {
int sum = nums[a]+nums[b]+nums[c]+nums[d];
if(sum==target) {
result.push_back({nums[a],nums[b],nums[c],nums[d]}); // 每次加入的 vector 都是升序的,hashmap 则不一定,需要判断!!!
++c;
--d;
}
else if(sum < target) {
++c;
}
else {
--d;
}
}
}
}
sort(result.begin(),result.end());
result.erase(unique(rusult.begin(),result.end()),result.end());
return result;
} vector<vector<int>> fourSum(vector<int>& nums,int target) { // STL::hashmap
vector<vector<int>> result;
if(nums.size()<) return result
sort(nums.begin(),nums.end()); map<int,vector<pair<int,int>>> cache;
for(int a=;a<nums.size();++a) {
for(int b=a+;b<nums.size();++b) {
cache[nums[a]+nums[b]].push_back(make_pair(a,b))
}
} for(int c=;c<nums.size();++c) {
for(int d=c+;d<nums.size();++c) {
int key = target - nums[c] - nums[d];
if(cache.find(key)==cache.end()) continue; for(int i=;i<cache[key].size();++i) {
if(c<=cache[key].second) continue; // 有重叠
vector<pair<int,int>>& vec = cache[key];
result.push_back({nums[vec[i].first],nums[vec[i].second],nums[c],nums[d]});
}
}
}
sort(result.begin(),result.end());
result.erase(unique(result.begin(),result.end()),result.end());
return result;
}
fourSum
9, removeElement
int removeElement1(vector<int>& nums,int target) { // 重组
int index=;
for(int i=;i<nums.size();++i) {
if(nums[i]!=target)
nums[index++]=nums[i];
}
return index;
} int removeElement2(vector<int>& nums,int target) { // 覆盖
int index=;
for(int i=;i<nums.size();++i) {
if(nums[i]==target)
continue;
nums[index++]=nums[i];
}
return index;
} int removeElement3(vector<int>& nums,int target) { // STL::erase
vector<int>::iterator it=nums.begin();
while(it!=nums.end()){
if(*it==target)
it = nums.erase(it);
else
++it;
}
return nums.size();
} int removeElement4(vector<int>& nums,int target) { // STL::distance STL::remove(类似于 unique函数)
return distance(nums.begin(),remove(nums.begin(),nums.end(),target));
}
removeElement
10, trapWater
int trapWater1(const vector<int>& heights) { // 左右扫描,动态规划思想
int result = ;
const int n = heights.size(); vector<int> maxLefts(n,);
int maxLeftValue = ;
for(int i=;i<n;++i) { // 从左向右扫描,注意这种赋值方法 ,保持左边的最大值
maxLefts[i] = maxLeftValue;
maxLeftValue = max(maxLeftValue,heights[i]);
}
vector<int> maxRights(n,); // 从右向左扫描,相同的赋值方法 ,保持右边的最大值
int maxRightValue = ;
for(int j=n-;j>=;--j) {
maxRights[j] = maxRightValue;
maxRightValue = max(maxRightValue,heights[j]);
}
for(int k=;k<n;++k) {
int diff = min(maxLefts[k],maxRights[k]);
if(diff>heights[k]) {
result += diff - heights[k];
}
}
return result;
} int trapWater2(const vector<int>& heights) { // 左右夹逼思想
int result=;
int l=,r=heights.size()-;
while(l < r) {
int mn = min(heights[l],heights[r]);
if(mn == heights[l]) {
++l;
while(mn>heights[l] && l < r)
result += mn - heights[l++];
}
else {
--r;
while(mn > heights[r] && l < r)
result += mn - heights[r--];
}
}
return result;
} int trapWater3(const vector<int>& heights) { // 对每个可能存水的柱子进行讨论,动态规划用的数组类似缓存的作用
int result = ;
const int n = heights.size()-;
int maxLeft = ;
int maxRight = ;
for(int i=;i<n-;++i) { // 每一个可能存雨的柱子
for(int j=;j<i;++j) { // 找左边最大的柱子
maxLeft = max(heights[j-],heights[j]);
}
for(int k=i+;k<n-;++k) { // 找右边最大的柱子
maxRight = max(heights[k],heights[k+]);
}
int diff = min(maxLeft,maxRight);
if(diff > heights[i])
result += diff - heights[i];
}
return result;
}
trapWater
11, climbStairs
int climbStairs1(int n) { // 迭代
int prev = ;
int curr = ;
for(int i=;i<=n;++i) {
int temp = curr;
curr = prev + curr;
prev = temp;
}
return curr;
} int climbStairs2(int n) { // 递归(效率低)
if(n== || n==) return n;
return climbStairs2(n-) + climbStairs2(n-);
} int climbStairs3(int n) { // 数学公式法
const double s = sqrt();
return floor((pow((+s)/,n+) + pow((-s)/,n+))/s + 0.5); // 数学公式
}
climbStairs
12, grayCode
vector<int> grayCode1(int n){ // 数学公式方式
int size = << n; //2^n
vector<int> result;
result.reserve(size);
for (int i = ; i < size; ++i)
result.push_back(i ^ (i >> ));
return result;
} vector<int> grayCode2(int n) { // 暂时未看懂
vector<int> result;
result.reserve( << n);
result.push_back();
for (int i = ; i < n; ++i) {
const int highest_bit = << i;
for (int j = result.size() - ; j >= ; --j) {
result.push_back(highest_bit | result[j]);
}
}
return result;
}
grayCode
13, candy
int candy(vector<int>& ratings){
const int n = ratings.size();
vector<int> nums(n, );
for (int i = ; i < n-; ++i){
if (ratings[i] < ratings[i+])
nums[i+] = nums[i] + ;
}
for (int j = n - ; j>; --j){
if (ratings[j] < ratings[j - ])
nums[j - ] = max(nums[j - ], nums[j] + );
}
return accumulate(nums.begin(), nums.end(),);
} int candyII(vector<int>& ratings) { //思路同 上面 trapWater 的两次扫描
if (ratings.size() == ) return ;
vector<int> minLeft(ratings.size(), );
for (unsigned int i = ; i<ratings.size(); ++i){
if (ratings[i]>ratings[i - ])
minLeft[i] = minLeft[i - ] + ;
}
vector<int> minRight(ratings.size(), );
for (unsigned int j = ratings.size() - ; j >= ; --j){
if (ratings[j]>ratings[j + ]) //如果左边的等级高,而且左边的糖果又少的话
minRight[j] = max(minLeft[j], (minRight[j + ] + ));
}
int result = ;
for (unsigned int k = ; k<ratings.size(); ++k)
result += max(minLeft[k], minRight[k]); //取从左边和右边都最小的值中的最大值,这样就满足所有条件了。
return result;
}
candy
14,singleNumber(I)
#include<functional> //bit_xor<int>() int singleNumber1(vector<int>& nums){
int x = ;
for (unsigned int i = ; i < nums.size(); ++i)
x ^= nums[i];
return x;
} int singleNumber2(vector<int>& nums) {
return accumulate(nums.begin(), nums.end(), , bit_xor<int>());
}
singleNumber
singleNumber(II)
int singleNumberII(vector<int>& nums) {
int result = ;
for (int i = ; i < ; ++i){
int sum = ;
for (unsigned int j = ; j < nums.size(); ++j){
sum += (nums[j] >> i) & ; // 求所有数的某一位是 1 的个数
}
result += (sum % ) << i; // result |= (sum % 3) << i;
}
return result;
}
singleNumber(II)1
int singleNumberII2(vector<int>& nums) {
const int W = sizeof(int)* ; // 一个整数的位数
int count[W]; // count[i] 表示在第 i 位出现 1 的个数
for (size_t i = ; i < nums.size(); ++i) {
for (int j = ; j < W; ++j) {
count[j] += (nums[i] >> j) & ;
count[j] %= ;
}
}
int result = ;
for (int i = ; i < W; ++i) { // 最后把唯一出现的数字计算出来
result += (count[i] << i);
}
return result;
}
singleNumber(II)2
博客中的题目来源于:https://github.com/soulmachine/leetcode (leetcode-cpp.pdf)
leetcode 数组类型题总结的更多相关文章
- leetcode 数组类型题
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h& ...
- leetcode 字符串类型题
1,Vaild Palindrome bool isPalindrome(string& s) { transform(s.begin(), s.end(), s.begin(), tolow ...
- leetcode 链表类型题总结
链表测试框架示例: // leetcodeList.cpp : 定义控制台应用程序的入口点.vs2013 测试通过 // #include "stdafx.h" #include ...
- leetcode 树类型题
树的测试框架: // leetcodeTree.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream& ...
- LeetCode数组刷题——448、48、240、769
1.[LeetCode448]:448. 找到所有数组中消失的数字 题目分析: 1-n之间有重复的,有没出现的,有出现一次.使用hashmap,空间复杂度为O(n) 方法一:哈希表,但是空间复杂度超过 ...
- leetcode 动态规划类型题
1,Triangle int mininumTotal(vector<vector<int>>& triangle) { ; i >= ; --i) { ; j ...
- Leetcode数组题*3
目录 Leetcode数组题*3 66.加一 题目描述 思路分析 88.合并两个有序数组 题目描述 思路分析 167.两数之和Ⅱ-输入有序数组 题目描述 思路分析 Leetcode数组题*3 66.加 ...
- 【js】Leetcode每日一题-数组异或操作
[js]Leetcode每日一题-数组异或操作 [题目描述] 给你两个整数,n 和 start . 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == ...
- 【js】Leetcode每日一题-解码异或后数组
[js]Leetcode每日一题-解码异或后数组 [题目描述] 未知 整数数组 arr 由 n 个非负整数组成. 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encode ...
随机推荐
- <记录> PHP Redis操作类
namespace common\controller; class Redis { public $redisObj = null; //redis实例化时静态变量 static protected ...
- STM32F103C8开发板原理图和管脚图
- Oracle 学习总结 - 表和索引的性能优化
表的性能 表的性能取决于创建表之前所应用的数据库特性,数据库->表空间->表,创建数据库时确保为每个用户创建一个默认的永久表空间和临时表空间并使用本地管理,创建表空间设为本地管理并且自动段 ...
- HTML Tables
Great job! In this lesson, you learned how to create a table, add data to it, and section the table ...
- tips___代码规范
函数变量尽可能置于最小作用域内,并在变量声明时进行初始化 变量声明的位置最好离第一次使用的位置越近越好:应使用初始化的方式代替声明再赋值. int x=0; rather than int x; x ...
- Eclipse实用操作
1.缩进:Tab 2.退格:Shift+Tab 3.包结构展开方式:Package Presentation 4.快速定位文件:按ctrl键不放,鼠标移至链接处 5.为属性快速生成相应的get和set ...
- unity 获取网络时间
http://cgi.im.qq.com/cgi-bin/cgi_svrtime public int year, mouth, day, hour, min, sec; public string ...
- NIPS 2016上22篇论文的实现汇集
http://blog.csdn.net/jiandanjinxin/article/details/54087592 日前,LightOn CEO 兼联合创始人 Igor Carron 在其博客上放 ...
- 对String值不可变的理解以及String类型的引用传递问题
今天复习java时,突然注意到了一句以前没有注意过的一句话,String 是final修饰的,其值是不可变的.当时看的一脸懵逼,String str = "abc"; str = ...
- VUE 计算属性 vs 侦听属性
计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 ...