[lintcode] 45.最大子数组差 [Medium]

描述

给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大。

返回这个最大的差值。

 

样例

给出数组[1, 2, -3, 1],返回 6

挑战

时间复杂度为O(n),空间复杂度为O(n)

解题思路

很久没刷题了,周末没事干,上lintcode刷刷题。

这道题第一眼大家应该都有一个思路,就是找左右的最大子数组然后相减。

我一直记得的一个处理连续型动规是要找global和local,太久没做题了手生了就直接这样做了。

后来发现两个问题,第一个是边界值难处理,比如local[0]是没有意义的(归根结底是不熟练);第二个是逻辑分的太细,一个函数就能解决的问题我写了四个函数解决;第三个是对local和global理解没有通透,有点太上层,如果好好往下层走就能发现有更直接的方式。先贴简洁版的code,后面的是繁琐但容易理解的code。

代码

简洁版本:

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer indicate the value of maximum difference between two substrings
     */

    int max_diff(vector<int>& nums){
        int size = nums.size();
        int* max = new int[size+1];
        int* min_reverse = new int[size+1];
        long sum = 0;
        int max_num = INT_MIN;
        for(int i=0; i<size; i++){
            sum += nums[i];
            max_num = max_num > sum ? max_num : sum;
            if(sum < 0) sum = 0;
            max[i] = max_num;
        }
        sum = 0;
        int min_num = INT_MAX;
        for(int i=size-1; i>=0; i--){
            sum += nums[i];
            min_num = min_num < sum ? min_num : sum;
            if(sum > 0) sum = 0;
            min_reverse[i] = min_num;
        }
        int res = 0;
        for(int i=0; i<size-1; i++){
            int tmp = abs(max[i] - min_reverse[i+1]);
            res = tmp > res ? tmp : res;
        }
        return res; 
    }

    int maxDiffSubArrays(vector<int> &nums) {
        // write your code here
        int res_left_max_right_min = max_diff(nums);
        reverse(nums.begin(), nums.end());
        int res_left_min_right_max = max_diff(nums);
        return res_left_max_right_min > res_left_min_right_max? res_left_max_right_min:res_left_min_right_max;
    }
    
};

 

 

繁琐版本:

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: An integer indicate the value of maximum difference between two substrings
     */
    int max_num(int a, int b, int c){
        int first_max = a>b?a:b;
        return first_max >c? first_max:c;
    }
    
    int min_num(int a, int b, int c){
        int first_max = a>b?b:a;
        return first_max >c? c:first_max;
    }
    
    void get_min_global(int* global, int* local, int size, int* res){
        for(int i=1; i<size-1; i++){
            res[i] = global[i] < local[i] ? global[i]:local[i];
        }
    }
    void get_max_global(int* global, int* local, int size, int* res){
        for(int i=1; i<size-1; i++){
            res[i] = global[i] > local[i] ? global[i]:local[i];
        }
    }
    
    void maxSubArrays(vector<int> &nums,int* max_global){
        int size = nums.size();
        int* max_local = new int[size+1];
        max_global[0] = nums[0];
        max_local[0] = -(1<<30);
        for(int i=1; i<size; i++){
            max_local[i] = max_global[i-1] > max_local[i-1]?max_global[i-1]:max_local[i-1];
            max_global[i] = max_global[i-1]+nums[i] > nums[i]?max_global[i-1]+nums[i]:nums[i];
        }
        get_max_global(max_global, max_local, size, max_global);
    }
    void minSubArrays(vector<int> &nums, int* max_global){
        int size = nums.size();
        int* max_local = new int[size+1];
        max_global[0] = nums[0];
        max_local[0] = (1<<30);
        for(int i=1; i<size; i++){
            max_local[i] = max_global[i-1] < max_local[i-1]?max_global[i-1]:max_local[i-1];
            max_global[i] = max_global[i-1]+nums[i] < nums[i]?max_global[i-1]+nums[i]:nums[i];
        }
        get_min_global(max_global, max_local, size, max_global);
    }
    void max_reverseSubArrays(vector<int> &nums, int* max_global){
        int size = nums.size();
        int* max_local = new int[size+1];
        max_global[size-1] = nums[size-1];
        max_local[size-1] = -(1<<30);
        for(int i=size-2; i>=0; i--){
            max_local[i] = max_global[i+1] > max_local[i+1]?max_global[i+1]:max_local[i+1];
            max_global[i] = max_global[i+1]+nums[i] > nums[i]?max_global[i+1]+nums[i]:nums[i];
        }
        get_max_global(max_global, max_local, size, max_global);
    }
    void min_reverseSubArrays(vector<int> &nums, int* max_global){
        int size = nums.size();
        //int* max_global = new int[size+1];
        int* max_local = new int[size+1];
        max_global[size-1] = nums[size-1];
        max_local[size-1] = (1<<30);
        for(int i=size-2; i>=0; i--){
            max_local[i] = max_global[i+1] < max_local[i]?max_global[i+1]:max_local[i];
            max_global[i] = max_global[i+1]+nums[i] < nums[i]?max_global[i+1]+nums[i]:nums[i];
        }
        get_min_global(max_global, max_local, size, max_global);
    }
    void print(int* arr, int size){
        for(int i=0; i<size; i++){
            cout << arr[i] << " ";
        }
        cout << endl;
    }
    
    int maxDiffSubArrays(vector<int> &nums) {
        // write your code here
        int size = nums.size();
        if(size == 2){
            return abs(nums[0] - nums[1]);
        }
        
        int* max_global = new int[size+1];
        int* min_global = new int[size+1];
        int* max_reverse_global = new int[size+1];
        int* min_reverse_global = new int[size+1];
        maxSubArrays(nums, max_global);
        max_reverseSubArrays(nums, max_reverse_global);
        minSubArrays(nums, min_global);
        min_reverseSubArrays(nums,min_reverse_global);
        
        // print(max_global,size);
        // print(min_global,size);
        // print(max_reverse_global,size);
        // print(min_reverse_global,size);
        int res = -1;
        for(int cut_pos = 0; cut_pos < size -1; cut_pos++){
            int tmp1 = abs(max_global[cut_pos] - min_reverse_global[cut_pos+1]);
            int tmp2 = abs(max_reverse_global[cut_pos+1] - min_global[cut_pos]);
            res = max_num(res, tmp1, tmp2);
        }
        return res;
    }
    
};

 

在uni.app中,定义数组可以通过在组件中使用props来传递父组件传递的数据。在组件中,可以通过在props中声明数组类型的参数来定义传入的数组。例如:props: { imgList: { type: Array, default: function() { return [] } } }。这样就可以在组件中使用imgList这个属性来获取父组件传递的数组数据。 另外,在处理数组时,可以使用一些处理代码来对数组进行操作。比如可以使用slice方法将数组分成多个小数组。例如,可以使用以下代码将imgList数组每两个元素切成一个新的数组: let newArr = []; for (var i = 0; i < this.imgList.length; i += 2) { newArr.push(this.imgList.slice(i, i + 2)) } console.log(newArr) 这样就可以将imgList数组按每两个元素进行切割,并将切割后的数组存储在newArr变量中。 需要注意的是,由于JavaScript的限制,Vue不能直接检测数组的变动。当直接通过索引设置数组项或修改数组的长度时,Vue无法自动更新界面。为了解决这个问题,可以使用Vue提供的一些数组方法来操作数组,例如使用Vue.set或Vue.delete来修改数组。另外,也可以通过使用Vue提供的非变异方法来操作数组,例如concat、slice等方法。具体的注意事项可以参考Vue的官方文档。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [uni-app快速入手 ——(5)项目实战 一 自定义组件+组件传值,uni.createAnimation()在app中如果是数组渲染...](https://blog.csdn.net/csl125/article/details/105663324)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [uni-app 处理数组(将一维数组转二维数组)](https://blog.csdn.net/qq_42543264/article/details/124192066)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值