leetcode 数组类型题总结

1,removeDuplicates(I)

 1 int removeDuplicatesI(vector<int>& nums){  // 重新组织数组,同 removeDuplicates2IV
 2     int index = 0;
 3     for(int i=0;i<nums.size();++i){
 4         if(i>0 && nums[i] == nums[i-1])
 5             continue; 
 6         nums[index++] = nums[i];
 7     }
 8     return index;
 9 } 
10 int removeDuplicatesII(vector<int>& nums) { // 数组覆盖操作 
11     if(nums.empty()) return 0;
12     int index = 1;
13     for(int i=1;i<nums.size();++i) {
14         if(nums[i-1] != nums[i])
15             nums[index++] = nums[i];
16     }
17     return index;
18 }
19 int removeDuplicatesIII(vector<int>& nums) {  //  STL::hashmap 
20     map<int,int> mapping;
21     if(nums.empty()) return 0;
22     for(int i=0;i<nums.size();++i) {
23         if(mapping.find(nums[i]) != mapping.end())
24             mapping[nums[i]] += 1;
25         else
26             mapping[nums[i]] = 1;
27     }
28     return mapping.size();
29 }
30 int removeDuplicatesIV(vector<int>& nums) {   // STL::set
31     set<int> myset;
32     for(int i=0;i<nums.size();++i)
33         myset.insert(nums[i]);
34     return myset.size();
35 }
36 int removeDuplicatesV(vector<int>& nums) {    // STL::unique,STL::distance
37     return distance(nums.begin(),unique(nums.begin(),nums.end()));
38 }
removeDuplicates(I)

 removeDuplicates(II)

 1 int removeDuplicates2I(vector<int>& nums) {  //  STL::haspmap 
 2     map<int,int> mapping;
 3     for(int i=0;i<nums.size();++i) {
 4         if(mapping.find(nums[i]) != mapping.end()){
 5             if(mapping.find(nums[i])->second == 2)
 6                 mapping.find(nums[i])->second = 2;
 7             else
 8                 mapping.find(nums[i])->second += 1;
 9         }
10         else
11             mapping[nums[i]] = 1;
12     }
13     int result=0;
14     for(map<int,int>::iterator it = mapping.begin();it != mapping.end();++it) {
15         result += it->second;
16     }
17     return result;
18 }
19 int removeDuplicates2II(vector<int>& nums) { // 思路同  removeDuplicatesII,覆盖操作,扩展性好 
20     if(nums.size()<3) return nums.size();
21     int index = 2; // index表示将要覆盖的三个相同元素的最后一个元素位置 
22     for(int i=2;i<nums.size();++i) {
23         if(nums[i] != nums[index-2])
24             nums[index++] = nums[i]; // 覆盖三个相同元素的最后一个 
25     }
26     return index;
27 }
28 int removeDuplicates2III(vector<int>& nums) {  // STL::erase 函数 
29     if(nums.size()<3) return nums.size();
30     for(vector<int>::iterator it=nums.begin();it!=nums.end()-2;++it)
31         if(*it == *(it + 1) && *it == *(it + 2))
32             it = nums.erase(it);
33     return nums.size();
34 } 
35 int removeDuplicates2IV(vector<int>& nums) {  // 重新组织数组 
36     int index = 0;  // index 表示下次放元素的位置 
37     for(int i=0;i<nums.size();++i){
38         if(i>1 && i<nums.size()-1 && nums[i]==nums[i-1] && nums[i]==nums[i+1])
39             continue; // 和左右两边相等的元素跳过(不放入重组数组中) 
40         nums[index++] = nums[i];
41     } 
42     return index;
43 }
removeDuplicates(II)

2, search(I)

 1 int search1(const vector<int>& nums,int target) {
 2     int first = 0;
 3     int last = nums.size()-1;
 4     while(first <= last) {
 5         int mid = first + (last - first)/2;
 6         if(nums[mid]==target) 
 7             return mid;
 8         else if(nums[first]<=nums[mid]) { // mid在左半部分 
 9             if(nums[first]<=target && target<nums[mid])
10                 last = mid - 1;
11             else
12                 first = mid + 1; 
13         }    
14         else {                         // mid在右半部分 
15             if(nums[mid]<target && target<=nums[last])
16                 first = mid + 1;
17             else
18                 last = mid - 1; 
19         }
20     }
21     return -1;
22 }
search(I)

    search(II)

 1 int search2(const vector<int>& nums,int target) {
 2     int first = 0;
 3     int last = nums.size()-1;
 4     while(first <= last) {
 5         int mid = first + (last - first)/2;
 6         if(nums[mid]==target)
 7             return mid;
 8             
 9         if(nums[first]<=nums[mid]) {      // mid 在左半部分 
10             if(nums[first]<nums[mid]) {   // nums[first] < nums[mid]
11                 if(nums[first]<=target && target<nums[mid])
12                     last = mid - 1;
13                 else
14                     first = mid + 1;
15             }
16             else                        // nums[first] == nums[mid]
17                 first++;                // 缩短查找区间 
18         }
19         else {                         //  nums[first] > nums[mid],mid 在右半部分 
20             if(nums[mid]<target && target<=nums[last])
21                 first = mid +1;
22             else
23                 last = mid - 1;
24         }
25     }
26     return -1;
27 }
search(II)

 3,连续序列长度

 1 int longestConsecutive(const vector<int>& nums) {
 2     map<int,bool> mapping;
 3     if(nums.empty()) return 0;
 4     int longestLengths = 1;
 5     for(int i=0;i<nums.size();++i) {
 6         mapping[nums[i]] = false;      // 用来表示该元素是否用过,因为同一连续序列的元素的连续序列长度相同,无序再计算 
 7     }
 8     
 9     for(int i=0;i<nums.size();++i) {
10         int Lengths = 1; 
11         if(mapping[nums[i]]) continue;
12         for(int j = 1;;++j) {       // 从右边往左边找 
13             map<int,bool>::iterator it = mapping.find(nums[i]-j);
14             if(it != mapping.end()){
15                 Lengths++;
16                 it->second = true;  
17             }    
18             else
19                 break;        
20         }
21         for(int j=1;;++j) {   // 从左往右找 
22             map<int,bool>::iterator it = mapping.find(nums[i]+j);
23             if(it != mapping.end()) {
24                 Lengths++;
25                 it->second = true;
26             }        
27             else
28                 break;
29         }
30         longestLengths = max(longestLengths,Lengths);
31     }
32     return longestLengths;
33 }
longestConsecutive

 4, 查询两个有序数组的第 K 个元素

1 int findMedianSortedArray(const vector<int>& A,const vector<int>& B) {
2     vector<int> result;
3     result.reserve(A.size()+B.size());
4     merge(A.begin(),A.end(),B.begin(),B.end(),result.begin());
5     return result[result.size()/2];
6     
7 }
findMedianSortedArray

5,twoSum

 1 vector<int> twoSum1(vector<int>& nums,int target) {  // STL::hashmap
 2     map<int,int> mapping;
 3     vector<int> result;
 4     for(int i=0;i<nums.size();++i)
 5         mapping[nums[i]] = i;
 6     for(int i=0;i<nums.size();++i){
 7         if(mapping.find(target-nums[i])!=mapping.end() && mapping[target-nums[i]]>i){
 8             result.push_back(i+1);
 9             result.push_back(target-nums[i]+1);
10             break;
11         }
12         return result;
13     }
14 } 
15 
16 vector<int> twoSum2(vector<int>& nums,int target) {  // 先排序,再左右夹逼 
17     vector<int> result; 
18     int first = 0;  // 保存元素下标 
19     int last = nums.size()-1;
20     sort(nums.begin(),nums.end());
21     while(first<last) {
22         if(nums[first] + nums[last] == target){
23             result.push_back(first+1);
24             result.push_back(last+1);
25             break;
26         }
27         if(nums[first] + nums[last] > target) {
28             last--;
29         }
30         else {
31             first++;
32         }
33     }
34     return result;
35 }
twoSum

6, threeSum

 1 vector<vector<int> > threeSumI(vector<int>& nums) {  //跳过重复的数 
 2     vector<vector<int> > result;
 3     const int target = 0;
 4     vector<int>::iterator it;
 5     for(it=nums.begin();it<nums.end()-2;++it) { // 遍历第一个数,剩余两个数进行夹逼 
 6         vector<int>::iterator j=it+1;
 7         vector<int>::iterator k=nums.end()-1;
 8         if(it!=nums.begin() && *it == *(it-1)) continue;
 9         while(j < k) {
10             if(*it + *j + *k == target){
11                 result.push_back({*it,*j,*k});
12                 ++j;
13                 --k;
14                 while(*j == *(j-1) && *k = *(k+1) && j < k) ++j; // 跳过重复的数 
15             }
16             else if(*it + *j + *k < target){
17                 ++j;
18                 while(*j == *(j-1) && j < k) ++j;  // 跳过重复 
19             } 
20             else {
21                 --k;
22                 while(*k = *(k+1) && j < k) --k;   // 跳过重复 
23             }
24         }
25     }
26     return result;
27 }
28 
29 vector<vector<int>> threeSumII(vector<int>& nums) {  //不跳过重复的数 ,最后直接去重 
30     vector<vector<int>> result;
31     const int target = 0;
32     vector<int>::iterator it;
33     for(it=nums.begin();it<nums.end()-2;++it) { 
34         vector<int>::iterator j=it+1;
35         vector<int>::iterator k=nums.end()-1;
36         if(it!=nums.begin() && *it == *(it-1)) continue;
37         while(j < k) {
38             if(*it + *j + *k == target){
39                 result.push_back({*it,*j,*k});
40                 ++j;
41                 --k;
42             }
43             else if(*it + *j + *k < target){
44                 ++j; 
45             } 
46             else {
47                 --k; 
48             }
49         }
50     }
51     sort(result.begin(),result.end(),less<int>());    // 去重 
52     result.erase(unique(result.begin(),result.end()),result.end()); 
53     return result;
54 }
55 
56 vector<vector<int>> threeSumIII(vector<int>& nums) { // STL::hashmap
57     vector<vector<int>> result;
58     map<int,vector<pair<int,int>>> cache;
59     const int target = 0;
60     if(nums.size()<3) return result;
61     sort(nums.begin(),nums.end());
62     for(int i=0;i<nums.size();++i){
63         for(int j=i+1;j<nums.size();++j) {
64             cache[nums[i]+nums[j]].push_back(make_pair(i,j));
65         }
66     } 
67     for(int i=0;i<nums.size();++i) {
68         const int key = target - nums[i];
69         if(cache.find(key)==cache.end()) continue;
70         
71         for(int j=0;j<cache[key].size();++j) {
72             if(i<=cache[key].second)    //不会出现  [1,2,3],[1,3,2] [2,1,3]都被加入的情况,如果这行不写,最后需要对每个新加入的 vector 排序,然后加入,最后判重。 
73                 continue;
74             vector<pair<int,int>>& vec = cache[key];
75             result.push_back({nums[vec[i].first],nums[vec[i].second],nums[i]});
76         }
77     }
78     sort(result.begin(),result.end());   // 可能有重复值,必须去重!比如:nums=[0,0,0,0,0,0],target=0 
79     result.erase(unique(result.begin(),result.end()),result.end());
80     return result;
81 }
threeSum

7, threeSumClose

 1 int threeSumClose(vector<int>& nums,int target) {
 2     int result = 0;
 3     int minGap = INT_MAX;
 4     sort(nums.begin(),nums.end());
 5     for(int i=0;i<nums.size()-2;++i) {
 6         int j=i+1;
 7         int k=nums.size()-1;
 8         while(j<k) {
 9             int sum = nums[i]+nums[j]+nums[k];
10             int gap = abs(target-sum);
11             if(gap<minGap) {
12                 result = sum;
13                 minGap = gap;
14             }
15             if(sum<target) ++j;
16             else           --k;
17         } 
18     }
19     return result;
20 } 
threeSumClose

8, fourSum

 1 vector<vector<int>> fourSum(vector<int>& nums,int target) { //先排序,在两边夹逼 
 2     vector<vector<int>> result;
 3     if(nums.size()<4) return result;
 4     sort(nums.begin(),nums.end());
 5     for(int a=0;a<nums.size()-3;++a) {
 6         for(int b=a+1;b<nums.size()-2;++b) {
 7             int c=b+1;
 8             int d=nums.size()-1;
 9             while(c < d) {
10                 int sum = nums[a]+nums[b]+nums[c]+nums[d];
11                 if(sum==target) {
12                     result.push_back({nums[a],nums[b],nums[c],nums[d]});  // 每次加入的 vector 都是升序的,hashmap 则不一定,需要判断!!! 
13                     ++c;
14                     --d;
15                 }
16                 else if(sum < target) {
17                     ++c;
18                 }
19                 else {
20                     --d;
21                 }
22             }
23         }
24     }
25     sort(result.begin(),result.end());
26     result.erase(unique(rusult.begin(),result.end()),result.end());
27     return result;
28 }
29 
30 
31 vector<vector<int>> fourSum(vector<int>& nums,int target) {  // STL::hashmap
32     vector<vector<int>> result;
33     if(nums.size()<4) return result
34     sort(nums.begin(),nums.end());
35     
36     map<int,vector<pair<int,int>>> cache;
37     for(int a=0;a<nums.size();++a) {
38         for(int b=a+1;b<nums.size();++b) {
39             cache[nums[a]+nums[b]].push_back(make_pair(a,b))
40         }
41     }
42     
43     for(int c=0;c<nums.size();++c) {
44         for(int d=c+1;d<nums.size();++c) {
45             int key = target - nums[c] - nums[d];
46             if(cache.find(key)==cache.end()) continue;
47             
48             for(int i=0;i<cache[key].size();++i) {
49                 if(c<=cache[key].second) continue; // 有重叠
50                 vector<pair<int,int>>& vec = cache[key];
51                 result.push_back({nums[vec[i].first],nums[vec[i].second],nums[c],nums[d]});
52             }
53         }
54     }
55     sort(result.begin(),result.end());
56     result.erase(unique(result.begin(),result.end()),result.end());
57     return result; 
58 }
59  
fourSum

 9, removeElement

 1 int removeElement1(vector<int>& nums,int target) { // 重组 
 2     int index=0;
 3     for(int i=0;i<nums.size();++i) {
 4         if(nums[i]!=target)
 5             nums[index++]=nums[i];
 6     }
 7     return index;
 8 }
 9 
10 int removeElement2(vector<int>& nums,int target) { // 覆盖 
11     int index=0;
12     for(int i=0;i<nums.size();++i) {
13         if(nums[i]==target)
14             continue;
15         nums[index++]=nums[i];
16     }
17     return index;
18 } 
19 
20 int removeElement3(vector<int>& nums,int target) {  // STL::erase
21     vector<int>::iterator it=nums.begin();
22     while(it!=nums.end()){
23             if(*it==target)
24                 it = nums.erase(it);
25             else
26                 ++it;
27     }
28     return nums.size();        
29 } 
30 
31 int removeElement4(vector<int>& nums,int target) {  // STL::distance  STL::remove(类似于 unique函数)
32     return distance(nums.begin(),remove(nums.begin(),nums.end(),target));
33 }
removeElement

 10, trapWater

 1 int trapWater1(const vector<int>& heights) {  // 左右扫描,动态规划思想 
 2     int result = 0;
 3     const int n = heights.size();
 4     
 5     vector<int> maxLefts(n,0);
 6     int maxLeftValue = 0;
 7     for(int i=0;i<n;++i) {  // 从左向右扫描,注意这种赋值方法 ,保持左边的最大值 
 8         maxLefts[i] = maxLeftValue;
 9         maxLeftValue =  max(maxLeftValue,heights[i]);
10     }
11     vector<int> maxRights(n,0);  // 从右向左扫描,相同的赋值方法 ,保持右边的最大值 
12     int maxRightValue = 0;
13     for(int j=n-1;j>=0;--j) {
14         maxRights[j] = maxRightValue;
15         maxRightValue = max(maxRightValue,heights[j]);
16     } 
17     for(int k=0;k<n;++k) {
18         int diff = min(maxLefts[k],maxRights[k]);
19         if(diff>heights[k]) {
20             result += diff - heights[k];
21         }
22     } 
23     return result;
24 }
25 
26 int trapWater2(const vector<int>& heights) {  // 左右夹逼思想 
27     int result=0;
28     int l=0,r=heights.size()-1;
29     while(l < r) {
30         int mn = min(heights[l],heights[r]);
31         if(mn == heights[l]) {
32             ++l;
33             while(mn>heights[l] && l < r)
34                 result += mn - heights[l++];
35         }
36         else {
37             --r;
38             while(mn > heights[r] && l < r) 
39                 result += mn - heights[r--];
40         }
41     }
42     return result;
43 }
44 
45 int trapWater3(const vector<int>& heights) {  // 对每个可能存水的柱子进行讨论,动态规划用的数组类似缓存的作用 
46     int result = 0;
47     const int n = heights.size()-1;
48     int maxLeft = 0;
49     int maxRight = 0; 
50     for(int i=1;i<n-1;++i) {  // 每一个可能存雨的柱子 
51         for(int j=0;j<i;++j) {  // 找左边最大的柱子 
52             maxLeft = max(heights[j-1],heights[j]);
53         } 
54         for(int k=i+1;k<n-1;++k) {  // 找右边最大的柱子 
55             maxRight = max(heights[k],heights[k+1]);
56         }
57         int diff = min(maxLeft,maxRight);
58         if(diff > heights[i])
59             result += diff - heights[i];
60     }
61     return result;
62 } 
trapWater

 11,  climbStairs

 1 int climbStairs1(int n) {  // 迭代 
 2     int prev = 0;
 3     int curr = 1;
 4     for(int i=1;i<=n;++i) {
 5         int temp = curr;
 6         curr = prev + curr;
 7         prev = temp;
 8     }
 9     return curr;
10 }
11 
12 int climbStairs2(int n) {  // 递归(效率低) 
13     if(n==1 || n==2) return n;
14     return climbStairs2(n-1) + climbStairs2(n-2);  
15 } 
16 
17 int climbStairs3(int n) {  // 数学公式法 
18     const double s = sqrt(5);
19     return floor((pow((1+s)/2,n+1) + pow((1-s)/2,n+1))/s + 0.5); // 数学公式 
20 }
climbStairs

 12, grayCode

 1 vector<int> grayCode1(int n){  // 数学公式方式
 2     int size = 1 << n; //2^n
 3     vector<int> result;
 4     result.reserve(size);
 5     for (int i = 0; i < size; ++i)
 6         result.push_back(i ^ (i >> 1));
 7     return result;
 8 }
 9 
10 vector<int> grayCode2(int n) {  // 暂时未看懂
11     vector<int> result;
12     result.reserve(1 << n);
13     result.push_back(0);
14     for (int i = 0; i < n; ++i) {
15         const int highest_bit = 1 << i;
16         for (int j = result.size() - 1; j >= 0; --j) {
17             result.push_back(highest_bit | result[j]);
18         }
19     }
20     return result;
21 }
grayCode

 13, candy

 1 int candy(vector<int>& ratings){
 2     const int n = ratings.size();
 3     vector<int> nums(n, 1);
 4     for (int i = 0; i < n-1; ++i){
 5         if (ratings[i] < ratings[i+1])
 6             nums[i+1] = nums[i] + 1;
 7     }
 8     for (int j = n - 1; j>0; --j){
 9         if (ratings[j] < ratings[j - 1])
10             nums[j - 1] = max(nums[j - 1], nums[j] + 1);
11     }
12     return accumulate(nums.begin(), nums.end(),0);
13 }
14 
15 int candyII(vector<int>& ratings) {  //思路同 上面 trapWater 的两次扫描
16     if (ratings.size() == 0) return 0;
17     vector<int> minLeft(ratings.size(), 1);
18     for (unsigned int i = 1; i<ratings.size(); ++i){
19         if (ratings[i]>ratings[i - 1])
20             minLeft[i] = minLeft[i - 1] + 1;
21     }
22     vector<int> minRight(ratings.size(), 1);
23     for (unsigned int j = ratings.size() - 2; j >= 0; --j){
24         if (ratings[j]>ratings[j + 1]) //如果左边的等级高,而且左边的糖果又少的话 
25             minRight[j] = max(minLeft[j], (minRight[j + 1] + 1));
26     }
27     int result = 0;
28     for (unsigned int k = 0; k<ratings.size(); ++k)
29         result += max(minLeft[k], minRight[k]);  //取从左边和右边都最小的值中的最大值,这样就满足所有条件了。 
30     return result;
31 }
candy

 14,singleNumber(I)

 1 #include<functional> //bit_xor<int>()
 2 
 3 int singleNumber1(vector<int>& nums){
 4     int x = 0;
 5     for (unsigned int i = 0; i < nums.size(); ++i)
 6         x ^= nums[i];
 7     return x;
 8 }
 9 
10 int singleNumber2(vector<int>& nums) {
11     return accumulate(nums.begin(), nums.end(), 0, bit_xor<int>());
12 }
singleNumber

   singleNumber(II)

 1 int singleNumberII(vector<int>& nums) {
 2     int result = 0;
 3     for (int i = 0; i < 32; ++i){
 4         int sum = 0;
 5         for (unsigned int j = 0; j < nums.size(); ++j){
 6             sum += (nums[j] >> i) & 1; // 求所有数的某一位是 1 的个数
 7         }
 8         result += (sum % 3) << i;    // result |= (sum % 3) << i;
 9     }
10     return result;
11 }
singleNumber(II)1

 

int singleNumberII2(vector<int>& nums) {
    const int W = sizeof(int)* 8;  // 一个整数的位数
    int count[W];  // count[i] 表示在第 i 位出现 1 的个数
    for (size_t i = 0; i < nums.size(); ++i) {
        for (int j = 0; j < W; ++j) {
            count[j] += (nums[i] >> j) & 1;
            count[j] %= 3;
        }
    }
    int result = 0;
    for (int i = 0; i < W; ++i) {  // 最后把唯一出现的数字计算出来
        result += (count[i] << i);
    }
    return result;
}
singleNumber(II)2

 

 

 

 

 

博客中的题目来源于:https://github.com/soulmachine/leetcode  (leetcode-cpp.pdf)

posted on 2019-02-18 20:27  爱笑的张飞  阅读(657)  评论(0编辑  收藏  举报

导航