求和爲aim的最長子數組以及擴展問題

求和爲aim的最長子數組
//
//  mosteor.cpp
//  AdvancedFour
//
//  Created by 吳珝君 on 2019/5/23.
//  Copyright © 2019年 閒着也是賢者. All rights reserved.
//

#include "mosteor.hpp"
#include <iostream>
#include <vector>
#include <map>
using namespace std;
/*
 求數組異或和的最多劃分: 這個問題的本質還是求和爲aim值的子數組的問題
 當一個數來了之後,我需要判斷,將其加進來使其構成新的劃分得到了劃分數量最多
 還是拋棄這個數,利用前面 i -1個數得到的劃分多。
 */

class Solution
{
    public:
    vector<int> mostEor(vector<int> arr)
    {
        vector<int> res;
        int *newarr = new int[arr.size()];
        fill(newarr, newarr+arr.size(), 0);
        for (int  i = 0; i < arr.size(); i++) {
            if (arr[i]%2 ==0) {
                newarr[i] = -1;
            }
            else
            newarr[i] = 1;
        }
        //求和爲0的最長子數組
        int start = -1;
        int end = -1;
        map<int, int> m;//存值和座標
        int sum = 0;
        for (int i = 0; i < arr.size(); i++)
        {
            sum +=newarr[i];
            if (m.count(sum) == 1)
            {
               
                if (end - start < i -m.find(sum)->second)
                {
                    start = m.find(sum)->second;
                    end = i;
                     cout << "最優劃分 " << start <<" " <<end<<endl;
                } 
            }
            else
            {
                m.insert(pair<int, int>(sum,i));
            }
            
            
        }
            
        for (int i = start; i <end; i++) {
            res.push_back(arr[i+1]);
            
        }
        
        return res;
        
    }
    
    
    
    
    
};

 int main()
 {
     vector<int> arr;
     srand((unsigned)time(NULL));
     for (int i = 0; i < 10; i++) {
         arr.push_back(i+ rand()%50);
         cout <<arr[i] <<"  ";
     }
     cout <<endl;
//     int k = rand()%100 +100;
  //   cout <<"aim :"<<k <<endl;
     Solution s;
     arr = s.mostEor(arr);
     for (int i = 0; i < arr.size(); i++) {
         cout <<arr[i]%2 << endl;
     }
 return 0;
 }
擴展問題:
求奇數和偶數個數相等的最長子數組
//
//  mosteor.cpp
//  AdvancedFour
//
//  Created by 吳珝君 on 2019/5/23.
//  Copyright © 2019年 閒着也是賢者. All rights reserved.
//

#include "mosteor.hpp"
#include <iostream>
#include <vector>
#include <map>
using namespace std;
/*
 求數組異或和的最多劃分: 這個問題的本質還是求和爲aim值的子數組的問題
 當一個數來了之後,我需要判斷,將其加進來使其構成新的劃分得到了劃分數量最多
 還是拋棄這個數,利用前面 i -1個數得到的劃分多。
 */

class Solution
{
    public:
    vector<int> mostEor(vector<int> arr)
    {
        vector<int> res;
        int *newarr = new int[arr.size()];
        fill(newarr, newarr+arr.size(), 0);
        for (int  i = 0; i < arr.size(); i++) {
            if (arr[i]%2 ==0) {
                newarr[i] = -1;
            }
            else
            newarr[i] = 1;
        }
        //求和爲0的最長子數組
        int start = -1;
        int end = -1;
        map<int, int> m;//存值和座標
        int sum = 0;
        for (int i = 0; i < arr.size(); i++)
        {
            sum +=newarr[i];
            if (m.count(sum) == 1)
            {
               
                if (end - start < i -m.find(sum)->second)
                {
                    start = m.find(sum)->second;
                    end = i;
                     cout << "最優劃分 " << start <<" " <<end<<endl;
                }
                
               
                
            }
            else
            {
                m.insert(pair<int, int>(sum,i));
            }
            
            
        }
            
        for (int i = start; i <end; i++) {
            res.push_back(arr[i+1]);
            
        }
        
        return res;
        
    }
    
    
    
    
    
};

 int main()
 {
     vector<int> arr;
     srand((unsigned)time(NULL));
     for (int i = 0; i < 10; i++) {
         arr.push_back(i+ rand()%50);
         cout <<arr[i] <<"  ";
     }
     cout <<endl;
//     int k = rand()%100 +100;
  //   cout <<"aim :"<<k <<endl;
     Solution s;
     arr = s.mostEor(arr);
     for (int i = 0; i < arr.size(); i++) {
         cout <<arr[i]%2 << endl;
     }
 return 0;
 }
擴展問題:
求子數組異或和爲0的最多劃分
//
//  mosteor.cpp
//  AdvancedFour
//
//  Created by 吳珝君 on 2019/5/23.
//  Copyright © 2019年 閒着也是賢者. All rights reserved.
//

#include "mosteor.hpp"
#include <iostream>
#include <vector>
#include <map>
using namespace std;
/*
求數組異或和的最多劃分: 這個問題的本質還是求和爲aim值的子數組的問題
 當一個數來了之後,我需要判斷,將其加進來使其構成新的劃分得到了劃分數量最多
 還是拋棄這個數,利用前面 i -1個數得到的劃分多。
 */

class Solution
{
    public:
    int mostEor(vector<int> arr)
    {
        if(arr.size() == 0)
        return 0;
        int xors =0;
        map<int, int> m;
        int dp[1000] = {0};
        if (arr[0] == 0)
        {
            dp[0] = 1;
        }
        m.insert(pair<int, int>(arr[0],0));
        m[xors] = arr[0];
        
        for (int i = 1; i < arr.size(); i++) {
            xors ^=arr[i];
            //如果有這樣的劃分
            if (m.count(xors))//
            {

                int l = dp[m.find(xors)->second] +1;
                int r = dp[i - 1];
                dp[i] = (l > r ? l : r);
            }
            else
            {
                dp[i] = dp[i - 1];
              
            }
              m[xors] = i;
            
        }

        return dp[arr.size()-1];
    }
    
    
    
    
    
};
/*
 int main()
 {
 vector<int> arr;
 srand((unsigned)time(NULL));
 for (int i = 0; i < 10; i++) {
 arr.push_back(i+ rand()%10);
 cout <<arr[i] <<"  ";
 }
 cout <<endl;
 Solution s;
     int count = s.mostEor(arr);
     cout <<count<<endl;
     
 return 0;
 }*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章