leetcode数组相关简单习题,玉米迪迪的刷题之旅(*╹▽╹*)

好啦好啦!我今天开始重鼓信心刷题啦!也不知道怎么回事一道简单的数组题开始有了思路,却总是写不出来,但是也就是看了别的大佬的思路以及自己的回忆,突然发现!这个题的做法我的老师讲过!一下子又发现我回忆起来后就自己写出回来啦!呜呜呜!原来学习就是一件不断重复的事情!我爱了!

1、找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000

思路:
看到这个题我的第一反应是计数啊,创建一个变量count,只要重复出现就count++。
那怎么判断重复呐?我开始想的是使用两个for循环i,j,j总是比i多1,只要nums[i] = nums[j],就count++,最后返回nums[i]就可以了。但是这样时间复杂度就高了,而且如果出现两个以上都有重复的数字,count就会被覆盖,想的是虽然覆盖了但是至少应该会输出在后边会重复的数字,于是乎出现了以下愚蠢的代码。结果是根本就不行!if好像不起作用!别问!问就是我太菜了!呜呜呜呜。

在这里插入图片描述
于是乎我转换了思路如下:
1、创建一个计数数组,用来记录每个数字出现的次数
2、使用一个for循环对数字进行遍历,或者使用foreach遍历数组也行哦
3、将每个数nums[i]与计数数组的角标对应,计数数组的每一个数大于1后便返回这个计数数组的角标,即nums[i],这样就求得重复数字啦!

代码如下:

class Solution {
    public int findRepeatNumber(int[] nums){
        int n = nums.length;
        int[] arr = new int[n]; //创建一个长度为n的计数数组
        for(int i = 0; i < n; i++){  //使用for循环对nums数组进行遍历
            arr[nums[i]]++;   //因为原来的计数数组每一处的默认值都为0,这里使i处的数字nums[i]与计数数组的角标对应并计数,每有一个相同的便+1
            if(arr[nums[i]] > 1){  //这里在筛选出现过两次以上的数
                return nums[i];   //返回这个数
            }
        }
        return -1;
    }
}

————————————————————————————

2、剑指 Offer 53 - I. 在排序数组中查找数字 I

统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
限制:
0 <= 数组长度 <= 50000

思路:
这道题本小白想到的就是直接遍历计数返回count就ok了。

class Solution {
    public int search(int[] nums, int target) {
        int count = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == target){
                count++;
            }
        }
        return count; 
    }
}

—————————————————————————————

3、剑指 Offer 39. 数组中出现次数超过一半的数字

又是一道不会的题啊!!!!
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
限制:
1 <= 数组长度 <= 50000

思路:我原本想的是这个题跟我做的第一道题挺像,但做着做着我发现他数组角标越界了,让我就很无语
然后看大佬题解发现了摩尔投票法 我菜死了

class Solution {
    public int majorityElement(int[] nums) {
        int x = 0, votes = 0, count = 0;
        for(int num : nums){
            if(votes == 0) {
                x = num;
            }
            votes += num == x ? 1 : -1;
        }
        // 验证 x 是否为众数
        for(int num : nums)
            if(num == x) {
                count++;
            }
        return count > nums.length / 2 ? x : 0; // 当无众数时返回 0
    }
}

—————————————————————————————

4、922. 按奇偶排序数组 II

给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。
对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。
你可以返回任何满足上述条件的数组作为答案。
示例:
输入:[4,2,5,7]
输出:[4,5,2,7]
解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。
提示:
2 <= A.length <= 20000
A.length % 2 == 0
0 <= A[i] <= 1000

思路:根据这个题我发现如果题目给出了两个条件的话,可以先满足一个条件,在这个条件满足后,把另一个作为前一个条件下输出的结果,最后再返回最终想要的得到的东西。
比如开始我把角标要满足i % 2 = = 1或i % 2 = =0,和数组里的元素 nums[i] % 2 = = 1 或 nums[i] % 2 = = 2都作为了判断条件,结果在写if时发现满足这个以后if里的执行内容不知道该如何写是好,要写的话也比较麻烦。
然后看了题解,学习了遍历两遍数组,就写出来了。

class Solution {
    public int[] sortArrayByParityII(int[] nums) {
        int n = nums.length;
        int[] array = new int[n];

        int i = 0; //从偶数开始
        for(int x : nums){
            if(x % 2 == 0){
                array[i] = x;
                i += 2;
            }
        }

        i = 1; //从奇数开始
        for(int x : nums){
            if(x % 2 == 1){
                array[i] = x;
                i += 2;
            }
        }
        return array;
    }
}

—————————————————————————————

5、905. 按奇偶排序数组

给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
你可以返回满足此条件的任何数组作为答案。
示例:
输入:[3,1,2,4]
输出:[2,4,3,1]
输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
提示:
1 <= A.length <= 5000
0 <= A[i] <= 5000

思路:
1、通过遍历数组找到里面的偶数
2、设置i,j两个角标,i用来遍历数组,j = 0,用来做交换
3、只要将偶数换到前面就可以了,所以在遍历时发现偶数时就把这个偶数换到数组的第一位,第二位…最后返回数组的值就可以了

class Solution {
    public int[] sortArrayByParity(int[] A) {
        int n = A.length;
        int j = 0;
        for(int i = 0; i < n; i++){
            int x = A[i];
            if(x % 2 == 0){
                int temp =A[j];
                A[j] = A[i];
                A[i] = temp;
                j++;
            }
        }
        return A;
    }
}

在这里插入图片描述
—————————————————————————————

6、面试题 17.10. 主要元素

数组中占比超过一半的元素称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回-1。
示例 1:
输入:[1,2,5,9,5,9,5,5,5]
输出:5
示例 2:
输入:[3,2]
输出:-1
示例 3:
输入:[2,2,1,1,1,2,2]
输出:2
说明:
你有办法在时间复杂度为 O(N),空间复杂度为 O(1) 内完成吗?

思路:这道题同理于上面的第三题,但是摩尔投票法是默认必定存在众数,但该题可能不存在众数,所以摩尔投票法得到的候选数,应该进行验证。
而且根据说明,这道题最先想到的便是使用摩尔投票法来做。

摩尔投票算法的时间和空间都很低,时间复杂度为O(n),空间复杂度为O(1),可以快速的计算出一个数组中出现次数过半的数即大多数(majority),算法核心思想是同加,异减。算法会保存一个当前大多数,和得分,当遇到一个数不是当前大多数时,得分会减一,当减到0时,大多数会发生改变,并且重置得分为1。
算法伪代码:

初始化元素 major = 0, count = 0
遍历数组中每一个元素x:
    if count == 0
        major = x
        count = 1
    else if major == x
        ++count
    else 
        --count
return major

————————————————
摩尔投票算法的理解摘抄于以下,原文链接:https://blog.csdn.net/sinat_30281495/article/details/87936774

代码:

7、两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 103
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案

思路:使用两个for循环,使得nums[i] + nums[j] =target,然后返回角标(来源于leetcode官方题解)
代码:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n = nums.length;
        for (int i = 0; i < n; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (nums[i] + nums[j] == target) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}

在这里插入图片描述
————————————————————————————————————

8、1480. 一维数组的动态和

给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。
请返回 nums 的动态和。
示例 1:
输入:nums = [1,2,3,4]
输出:[1,3,6,10]
解释:动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] 。
示例 2:
输入:nums = [1,1,1,1,1]
输出:[1,2,3,4,5]
解释:动态和计算过程为 [1, 1+1, 1+1+1, 1+1+1+1, 1+1+1+1+1] 。
示例 3:
输入:nums = [3,1,2,10,1]
输出:[3,4,6,16,17]
提示:
1 <= nums.length <= 1000
-10^6 <= nums[i] <= 10^6

思路:求和放入一个新的数组,并返回新数组

代码:

class Solution {
    public int[] runningSum(int[] nums) {
        int n = nums.length;
        int[] array = new int[n];
        int sum = 0;
        for(int i = 0; i < n; i++){
            sum += nums[i];
            array[i] = sum;
            }
        return array;
    }
}

在这里插入图片描述

————————————————————————————————————

9、1672. 最富有客户的资产总量

给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第 i​​​​​​​​​​​​ 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。
客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。
示例 1:
输入:accounts = [[1,2,3],[3,2,1]]
输出:6
解释:
第 1 位客户的资产总量 = 1 + 2 + 3 = 6
第 2 位客户的资产总量 = 3 + 2 + 1 = 6
两位客户都是最富有的,资产总量都是 6 ,所以返回 6 。
示例 2:
输入:accounts = [[1,5],[7,3],[3,5]]
输出:10
解释:
第 1 位客户的资产总量 = 6
第 2 位客户的资产总量 = 10
第 3 位客户的资产总量 = 8
第 2 位客户是最富有的,资产总量是 10
示例 3:
输入:accounts = [[2,8,7],[7,1,3],[1,9,5]]
输出:17
提示:
m = = accounts.length
n = = accounts[i].length
1 <= m, n <= 50
1 <= accounts[i][j] <= 100

思路:挨个求,再比较出最大

代码:

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

在这里插入图片描述
——————————————————————————————————————

10、1512. 好数对的数目

给你一个整数数组 nums 。
如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对 。
返回好数对的数目。
示例 1:
输入:nums = [1,2,3,1,1,3]
输出:4
解释:有 4 组好数对,分别是 (0,3), (0,4), (3,4), (2,5) ,下标从 0 开始
示例 2:
输入:nums = [1,1,1,1]
输出:6
解释:数组中的每组数字都是好数对
示例 3:
输入:nums = [1,2,3]
输出:0
提示:
1 <= nums.length <= 100
1 <= nums[i] <= 100

思路:两个for循环判断是否有相等的数且i < j
代码:

class Solution {
    public int numIdenticalPairs(int[] nums) {
        int n = nums.length;
        int count = 0;
        for(int i = 0; i < n; i++){
            for(int j = 1; j < n ;j++){
                if(nums[i] == nums[j] && i < j){
                    count++;
                }
            }
        }
        return count;
    }
}

在这里插入图片描述
——————————————————————————————————————

11、1431. 拥有最多糖果的孩子

给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。
对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目。
示例 1:
输入:candies = [2,3,5,1,3], extraCandies = 3
输出:[true,true,true,false,true]
解释:
孩子 1 有 2 个糖果,如果他得到所有额外的糖果(3个),那么他总共有 5 个糖果,他将成为拥有最多糖果的孩子。
孩子 2 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。
孩子 3 有 5 个糖果,他已经是拥有最多糖果的孩子。
孩子 4 有 1 个糖果,即使他得到所有额外的糖果,他也只有 4 个糖果,无法成为拥有糖果最多的孩子。
孩子 5 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子.
示例 2:
输入:candies = [4,2,1,1,2], extraCandies = 1
输出:[true,false,false,false,false]
解释:只有 1 个额外糖果,所以不管额外糖果给谁,只有孩子 1 可以成为拥有糖果最多的孩子。
示例 3:
输入:candies = [12,1,12], extraCandies = 10
输出:[true,false,true]
提示:
2 <= candies.length <= 100
1 <= candies[i] <= 100
1 <= extraCandies <= 50

思路:1、找最大值
2、创建一个布尔类型的线性表
3、让max+extraCabdies与max作比较,大则在线性表中增加ture,小则false

代码:

class Solution {
    public List<Boolean> kidsWithCandies(int[] candies, int extraCandies) {
        int n = candies.length;
        int max = candies[0];
        List list = new ArrayList<Boolean>(n);
        for(int i = 0 ; i < n; i++){
            if(candies[i] > max){
                max = candies[i];
            }
        }
        for(int j = 0; j < n; j++ ){
                int MAX = candies[j] + extraCandies;
                list.add(MAX >= max);
        }
        return list;
    }
}

在这里插入图片描述———————————————————————————————————————

12、1470. 重新排列数组

给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,…,xn,y1,y2,…,yn] 的格式排列。
请你将数组按 [x1,y1,x2,y2,…,xn,yn] 格式重新排列,返回重排后的数组。
示例 1:
输入:nums = [2,5,1,3,4,7], n = 3
输出:[2,3,5,4,1,7]
解释:由于 x1=2, x2=5, x3=1, y1=3, y2=4, y3=7 ,所以答案为 [2,3,5,4,1,7]
示例 2:
输入:nums = [1,2,3,4,4,3,2,1], n = 4
输出:[1,4,2,3,3,2,4,1]
示例 3:
输入:nums = [1,1,2,2], n = 2
输出:[1,2,1,2]
提示:
1 <= n <= 500
nums.length == 2n
1 <= nums[i] <= 10^3

思路:借鉴别人的交叉放入新数组(看了半天都没明白(ಥ﹏ಥ))
代码:

class Solution {
    public int[] shuffle(int[] nums, int n) {
        int index = 0;
        int[] result = new int[2 * n];
        for (int i = 0; i < n; i++) {
               result[index++] = nums[i];
               result[index++] = nums[n+i];
        }
        return result;
    }
}

在这里插入图片描述——————————————————————————————————————

13、1486. 数组异或操作

给你两个整数,n 和 start 。
数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n = = nums.length 。
请返回 nums 中所有元素按位异或(XOR)后得到的结果。
示例 1:
输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
“^” 为按位异或 XOR 运算符。
示例 2:
输入:n = 4, start = 3
输出:8
解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.
示例 3:
输入:n = 1, start = 7
输出:7
示例 4:
输入:n = 10, start = 5
输出:2
提示:
1 <= n <= 1000
0 <= start <= 1000
n == nums.length

思路:
按照题意模拟即可:
1、初始化 ans=0\rm ans = 0ans=0
2、遍历区间 [0,n−1][0, n - 1][0,n−1] 中的每一个整数 iii,令 ans\rm ansans 与每一个 ${\rm start} + 2 \times i $ 做异或运算
3、最终返回 ans\rm ansans,即我们需要的答案
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/xor-operation-in-an-array/solution/shu-zu-yi-huo-cao-zuo-by-leetcode-solution/
来源:力扣(LeetCode)

代码:

class Solution {
    public int xorOperation(int n, int start) {
        int result = start, i;
            for (i = 1; i < n; i++){
                result = result ^ (start + i * 2);
            }
        return result;
    }
}

在这里插入图片描述

———————————————————————————————————————

14、1313. 解压缩编码列表

给你一个以行程长度编码压缩的整数列表 nums 。
考虑每对相邻的两个元素 [freq, val] = [nums[2i], nums[2i+1]] (其中 i >= 0 ),每一对都表示解压后子列表中有 freq 个值为 val 的元素,你需要从左到右连接所有子列表以生成解压后的列表。
请你返回解压后的列表。
示例 1:
输入:nums = [1,2,3,4]
输出:[2,4,4,4]
解释:第一对 [1,2] 代表着 2 的出现频次为 1,所以生成数组 [2]。
第二对 [3,4] 代表着 4 的出现频次为 3,所以生成数组 [4,4,4]。
最后将它们串联到一起 [2] + [4,4,4] = [2,4,4,4]。
示例 2:
输入:nums = [1,1,2,3]
输出:[1,3,3]
提示:
2 <= nums.length <= 100
nums.length % 2 == 0
1 <= nums[i] <= 100

思路:1、先求新数组的长度
2、再将元素一个个填入新数组

代码:

class Solution {
    public int[] decompressRLElist(int[] nums) {
        int n = nums.length;
        int len = 0;
        for(int i = 0; i < n; i += 2){
            len += nums[i];
        }
        int[] res = new int[len];
        int index = 0;
        for(int i = 0; i < n; i+=2){
            int a = nums[i];
            while(a > 0){
                res[index] = nums[i+1];
                a--;
                index++;
            }
        }
        return res;    
    }
}

在这里插入图片描述
——————————————————————————————————————

15、1389. 按既定顺序创建目标数组

给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:
目标数组 target 最初为空。
按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
重复上一步,直到在 nums 和 index 中都没有要读取的元素。
请你返回目标数组。
题目保证数字插入位置总是存在。
示例 1:
输入:nums = [0,1,2,3,4], index = [0,1,2,2,1]
输出:[0,4,1,3,2]
解释:
nums index target
0 0 [0]
1 1 [0,1]
2 2 [0,1,2]
3 2 [0,1,3,2]
4 1 [0,4,1,3,2]
示例 2:
输入:nums = [1,2,3,4,0], index = [0,1,2,3,0]
输出:[0,1,2,3,4]
解释:
nums index target
1 0 [1]
2 1 [1,2]
3 2 [1,2,3]
4 3 [1,2,3,4]
0 0 [0,1,2,3,4]
示例 3:
输入:nums = [1], index = [0]
输出:[1]
提示:
1 <= nums.length, index.length <= 100
nums.length == index.length
0 <= nums[i] <= 100
0 <= index[i] <= i

思路:
1、创建一个新的数组target用来存放元素
2、(这三个数组的长度都相等)对target数组遍历前先判断target[i]处是否有元素,如果有元素,则需要将i以后的元素后移,再放入;如果没有,直接放入。
3、最后返回target

class Solution {
    public int[] createTargetArray(int[] nums, int[] index) {
        int[] target = new int[nums.length];
        for(int i = 0; i < nums.length; i++){
            for(int j = i; j > index[i]; j--){
                target[j] = target[j - 1]; //这里表示当前target[index[i]处有元素,需要把原来这个地方的位置全部后移,再放入。完成插入过程
            }
            target[index[i]] = nums[i];//该处无元素,直接放入
        }
        return target;
    }
}

在这里插入图片描述———————————————————————————————————————

16、1365. 有多少小于当前数字的数字

给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。
以数组形式返回答案。
示例 1:
输入:nums = [8,1,2,2,3]
输出:[4,0,1,1,3]
解释:
对于 nums[0]=8 存在四个比它小的数字:(1,2,2 和 3)。
对于 nums[1]=1 不存在比它小的数字。
对于 nums[2]=2 存在一个比它小的数字:(1)。
对于 nums[3]=2 存在一个比它小的数字:(1)。
对于 nums[4]=3 存在三个比它小的数字:(1,2 和 2)。
示例 2:
输入:nums = [6,5,4,8]
输出:[2,1,0,3]
示例 3:
输入:nums = [7,7,7,7]
输出:[0,0,0,0]
提示:
2 <= nums.length <= 500
0 <= nums[i] <= 100

思路:
1、创建一个计数数组count
2、双重for循环判断是否有比他大的数
3、返回count
但是时间和空间都不尽理想

class Solution {
    public int[] smallerNumbersThanCurrent(int[] nums) {
        int[] count = new int[nums.length];
        for(int i = 0; i < nums.length; i++){
            for(int j = 0;j < nums.length;j++){
                if(j != i && nums[j] < nums[i]){
                    count[i]++;
                }
            }
        }
        return count;
    }
}

在这里插入图片描述——————————————————————————————————————

17、1295. 统计位数为偶数的数字

给你一个整数数组 nums,请你返回其中位数为 偶数 的数字的个数。
示例 1:
输入:nums = [12,345,2,6,7896]
输出:2
解释:
12 是 2 位数字(位数为偶数)
345 是 3 位数字(位数为奇数)
2 是 1 位数字(位数为奇数)
6 是 1 位数字 位数为奇数)
7896 是 4 位数字(位数为偶数)
因此只有 12 和 7896 是位数为偶数的数字
示例 2:
输入:nums = [555,901,482,1771]
输出:1
解释:
只有 1771 是位数为偶数的数字。
提示:
1 <= nums.length <= 500
1 <= nums[i] <= 10^5

思路:
1、使用/运算符判断是奇数还是偶数,用while循环对nums[i]里的每个元素进行对10整除,并计数,放入数组,当然也要先把0单独拿出来说
2、对数组进行判断能对2取余为0的就是偶数
代码:

class Solution {
    public int findNumbers(int[] nums) {
        int[] count = new int[nums.length];
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == 0){  //如果数组里存在0,直接计数1
                count[i] = 1;
            }
            while(nums[i] != 0){  //使用while循环计数
                nums[i] = nums[i] / 10; 
                count[i]++;
            }
        }
        int res = 0;
        for(int i = 0; i < nums.length; i++){ //对count数组里的元素进行判断
            if(count[i] % 2 == 0){
                res++;
            }
        }
        return res;
    }
}

在这里插入图片描述——————————————————————————————————————

18、1572. 矩阵对角线元素的和

给你一个正方形矩阵 mat,请你返回矩阵对角线元素的和。
请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。
示例 1:
输入:mat = [[1,2,3],
[4,5,6],
[7,8,9]]
输出:25
解释:对角线的和为:1 + 5 + 9 + 3 + 7 = 25
请注意,元素 mat[1][1] = 5 只会被计算一次。
示例 2:
输入:mat = [[1,1,1,1],
[1,1,1,1],
[1,1,1,1],
[1,1,1,1]]
输出:8
示例 3:
输入:mat = [[5]]
输出:5
提示:
n = = mat.length = = mat[i].length
1 <= n <= 100
1 <= mat[i][j] <= 100

思路:
遍历整个矩阵,如果当前坐标 (i,j)(i, j)(i,j) 满足 i=ji = ji=j 或者 i+j=n−1i + j = n - 1i+j=n−1,就把当前的数字加入到答案中。(题解来源于官网)

代码:

class Solution {
    public int diagonalSum(int[][] mat) {
        int n = mat.length, sum = 0;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (i == j || i + j == n - 1) {
                        sum += mat[i][j];
                    }
                }
            }
        return sum;
    }
}

———————————————————————————————————————

19、1732. 找到最高海拔

有一个自行车手打算进行一场公路骑行,这条路线总共由 n + 1 个不同海拔的点组成。自行车手从海拔为 0 的点 0 开始骑行。
给你一个长度为 n 的整数数组 gain ,其中 gain[i] 是点 i 和点 i + 1 的 净海拔高度差(0 <= i < n)。请你返回 最高点的海拔 。
示例 1:
输入:gain = [-5,1,5,0,-7]
输出:1
解释:海拔高度依次为 [0,-5,-4,1,1,-6] 。最高海拔为 1 。
示例 2:
输入:gain = [-4,-3,-2,-1,4,3,2]
输出:0
解释:海拔高度依次为 [0,-4,-7,-9,-10,-6,-3,-1] 。最高海拔为 0 。
提示:
n == gain.length
1 <= n <= 100
-100 <= gain[i] <= 100

代码:

class Solution {
    public int largestAltitude(int[] gain) {
        int result = 0, temp= 0;
        for (int x : gain){
            temp += x;                 //用来计算当前高度
            result = Math.max(result, temp);      //每次更新最高的高度
        }
        return result;
    }
}

在这里插入图片描述

————————————————————————————

20、1299. 将每个元素替换为右侧最大元素

给你一个数组 arr ,请你将每个元素用它右边最大的元素替换,如果是最后一个元素,用 -1 替换。完成所有替换操作后,请你返回这个数组。
示例 1:
输入:arr = [17,18,5,4,6,1]
输出:[18,6,6,6,1,-1]
解释:
下标 0 的元素 --> 右侧最大元素是下标 1 的元素 (18)
下标 1 的元素 --> 右侧最大元素是下标 4 的元素 (6)
下标 2 的元素 --> 右侧最大元素是下标 4 的元素 (6)
下标 3 的元素 --> 右侧最大元素是下标 4 的元素 (6)
下标 4 的元素 --> 右侧最大元素是下标 5 的元素 (1)
下标 5 的元素 --> 右侧没有其他元素,替换为 -1
示例 2:
输入:arr = [400]
输出:[-1]
解释:下标 0 的元素右侧没有其他元素。
提示:
1 <= arr.length <= 104
1 <= arr[i] <= 105

思路:
1、两次遍历寻找第i个元素后的最大值
2、只要是出现比max大的元素,便更新max的值
3、由于最后一个元素后面没有元素,所以直接给它替换成-1
(虽然算法不咋地,但是我自己写出来了,我觉得自己很牛,以后会逐步改进的!(╹▽╹*))

代码:

class Solution {
    public int[] replaceElements(int[] arr) {
        int n = arr.length;
        for(int i = 0; i < n - 1; i++){ //遍历0-n-1的元素
            int max = arr[i + 1]; //把要替换的元素的后边一个数定为max
            for(int j = i + 1; j < n; j++){
                if(arr[j] >= max){
                    max = arr[j]; //但凡是大于max的元素,就更新max
                    arr[i] = arr[j]; //进行替换
                }  
            }
        }
        arr[n - 1] = -1;  //数组最后一个元素直接替换成-1
        return arr;
    }
}

在这里插入图片描述——————————————————————————————————————

21、1464. 数组中两元素的最大乘积

给你一个整数数组 nums,请你选择数组的两个不同下标 i 和 j,使 (nums[i]-1)(nums[j]-1) 取得最大值。
请你计算并返回该式的最大值。
示例 1:
输入:nums = [3,4,5,2]
输出:12
解释:如果选择下标 i=1 和 j=2(下标从 0 开始),则可以获得最大值,(nums[1]-1)
(nums[2]-1) = (4-1)(5-1) = 34 = 12 。
示例 2:
输入:nums = [1,5,4,5]
输出:16
解释:选择下标 i=1 和 j=3(下标从 0 开始),则可以获得最大值 (5-1)*(5-1) = 16 。
示例 3:
输入:nums = [3,7]
输出:12
提示:
2 <= nums.length <= 500
1 <= nums[i] <= 10^3

思路:
排序,数组最后两个数为最大的两个元素,最后返回(nums[n - 1]-1)*(nums[n - 2] - 1))
怎么说sort永远的神!!!

class Solution {
    public int maxProduct(int[] nums) {
        Arrays.sort(nums);
        return (nums[nums.length - 1] - 1 )* (nums[nums.length - 2] - 1);
    }
}

在这里插入图片描述————————————————————————————————————

22、561. 数组拆分 I

**给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
返回该 最大总和 。
示例 1:
输入:nums = [1,4,3,2]
输出:4
解释:所有可能的分法(忽略元素顺序)为:
(1, 4), (2, 3) -> min(1, 4) + min(2, 3) = 1 + 2 = 3
(1, 3), (2, 4) -> min(1, 3) + min(2, 4) = 1 + 2 = 3
(1, 2), (3, 4) -> min(1, 2) + min(3, 4) = 1 + 3 = 4
所以最大总和为 4
示例 2:
输入:nums = [6,2,6,5,1,2]
输出:9
解释:最优的分法为 (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9
提示:1 <= n <= 104
nums.length == 2 ^ n
-104 <= nums[i] <= 104 **
思路:依旧是排序然后for循环使每个nums[i + 2]处的数相加
代码:

class Solution {
    public int arrayPairSum(int[] nums) {
        Arrays.sort(nums);
        int result = 0;
        for (int i = 0; i < nums.length; i += 2) {
            result += nums[i];
        }
        return result;
    }
}

在这里插入图片描述
——————————————————————————————————————

23、1748. 唯一元素的和

给你一个整数数组 nums 。数组中唯一元素是那些只出现恰好一次的元素。
请你返回 nums 中唯一元素的 和 。
示例 1:
输入:nums = [1,2,3,2]
输出:4
解释:唯一元素为 [1,3] ,和为 4 。
示例 2:
输入:nums = [1,1,1,1,1]
输出:0
解释:没有唯一元素,和为 0 。
示例 3 :
输入:nums = [1,2,3,4,5]
输出:15
解释:唯一元素为 [1,2,3,4,5] ,和为 15 。
提示:
1 <= nums.length <= 100
1 <= nums[i] <= 100

思路:好家伙,感觉和最前面刷的几道题,思路一样的。
根据提示,因为给出的数组的元素都是大于1小于100的,所以
1、创建一个count计数数组,对nums数组进行遍历,count数组的角标就是nums[i],
2、对count数组进行遍历,如果count[i]等于1,就表示,这个元素为该数组的唯一元素
3、返回sum

代码:

class Solution {
    public int sumOfUnique(int[] nums) {
        int[] count = new int[101];
        for(int i : nums){
            count[i]++;
        }
        int sum = 0;
        for(int i = 0; i < 101; i++){
            if(count[i] == 1){
                sum += i;
            }
        }
        return sum;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值