• 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)

    所有博文均为原著,如若转载,请注明出处!
  • 相关阅读:
    #maven解决乱码问题
    #jquery隐藏和启用
    date类型时间比较大小
    xml<>编译
    Linux分区有损坏修复
    linux部署相关命令
    Java实现4位数吸血鬼数字算法
    Java冒泡算法及中位数算法
    DT梦工厂 第25课 Scala中curring实战详解
    DT梦工厂 第24讲 scala中sam转换实战详解
  • 原文地址:https://www.cnblogs.com/zpcoding/p/10397630.html
Copyright © 2020-2023  润新知