day09-1588/1672/283

56 阅读2分钟

第一题

题目

给你一个正整数数组 arr ,请你计算所有可能的奇数长度子数组的和。

子数组 定义为原数组中的一个连续子序列。

请你返回 arr 中 所有奇数长度子数组的和

思路- 没想出来,所以解题都是看的题解,之后复习时候补充

1、暴力破解,不过这个暴力破解主要需要思考的就是从哪循环,循环到哪,哪里结束

补充:

  • 三层循环,第一次层循环表示,从哪个元素开始遍历(start表示)
  • 第二层循环,表示start开始的奇数长度的数组
  • 已经在第二层循环到技奇数长度的数组了,第三层循环,获取每个数组的元素进行加和

2、使用前缀和-因为会有很多重复的数组计算,比如,子数组长度为3时,一定会用到子数组长度为1时计算的值,子数组长度为5时,一定会用到子数组长度为3时的计算的值...

补充:

  • 创建一个新数组,这个数组的每一个元素表示,输入数组的前i项和
  • 两层循环-第一次层循环表示,从哪个元素开始遍历(start表示)
  • 第二层循环,表示start开始的奇数长度的数组
  • 在第二层循环里就可以直接用上第一步的新数组

代码

1、暴力破解

    public int sumOddLengthSubarrays(int[] arr) {
        int sum = 0;
        int n = arr.length;
        for (int start = 0; start < n; start++) {
            for (int length = 1; start + length <= n; length += 2) {
                int end = start + length - 1;
                for (int i = start; i <= end; i++) {
                    sum += arr[i];
                }
            }
        }
        return sum;
    }

2、前缀和

class Solution {
    public int sumOddLengthSubarrays(int[] arr) {
        int n = arr.length;
        int[] prefixSums = new int[n + 1];
        for (int i = 0; i < n; i++) {
            prefixSums[i + 1] = prefixSums[i] + arr[i];
        }
        int sum = 0;
        for (int start = 0; start < n; start++) {
            for (int length = 1; start + length <= n; length += 2) {
                int end = start + length - 1;
                // 为什么减呢,因为你从start开始的,得减下去start之前的数组元素和
                sum += prefixSums[end + 1] - prefixSums[start];
            }
        }
        return sum;
    }

第二题

题目

给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第 i​​​​​​​​​​​​ 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。

客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户

思路

遍历啊,我也只能想到遍历,这,应该没有别的方法吧

代码

    public int maximumWealth(int[][] accounts) {
        int max = 0;
        for(int i = 0; i < accounts.length; i++) {
            int sum = 0;
            for(int j = 0; j < accounts[0].length; j++) {
                sum+= accounts[i][j];
            };
            if(sum > max) {
                max = sum;
            };
        };
        return max;

    }

第三题

题目

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作

思路

哇哦,就是说刷题啥用吧,这不就来了,第二道双指针类型题,详见day01第一题

代码

    public void moveZeroes(int[] nums) {
        if(nums.length == 1) {
            return ;
        }
        int i = 0;
        int j = 1;
        while(i < nums.length -1 && j < nums.length) {
            if(nums[i] == 0) {
                if(nums[j] == 0) {
                    j++;
                }else {
                    nums[i] = nums[j];
                    nums[j] =0;
                    i++;
                    j=i+1;
                }
            }else {
                i++;
                j=i+1;
            }
        }
    }