Leetcode数组题(Java作答)

目录

268.缺失数字

605.种花问题

581.最短无序连续子数组

724.寻找数组的中心索引

217.存在重复元素

35.搜索插入位置

27.移除元素

766.托普利茨矩阵

53.最大子序和

169.多数元素

849.到最近的人的最大距离

509.斐波那契数

1160.拼写单词

994.腐烂的橘子

1103.分糖果II

1013.将数组分成和相等的三个部分

892.三维形体的表面积

999.车的可用捕获量

888.公平的糖果交换

463.岛屿的周长


268.缺失数字

给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。

示例 1:

输入: [3,0,1]
输出: 2
示例 2:

输入: [9,6,4,2,3,5,7,0,1]
输出: 8

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/missing-number

class Solution {
    public int missingNumber(int[] nums) {
        int[] newnums=new int[nums.length+1];//创建1个长度为n+1的数组,角标是0~n
        for(int i=0;i<=nums.length-1;i++){//遍历给定的数组
            newnums[nums[i]]=1;//借鉴计数排序的思想,将nums中的数与新数组的角标相匹配,并将所匹配到角标索引的空间值改成1。那么遍历完后肯定角标在0~n中有一个数未匹配,这个数就是缺失数字
        }
        int j=0;
        for(int i=0;i<=newnums.length-1;i++){
            if(newnums[i]!=1){//找出未匹配的角标,角标代表的就是匹配的数字
                j=i;
            }
        }
        return j;
    }
}

605.种花问题

假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。

示例 1:

输入: flowerbed = [1,0,0,0,1], n = 1
输出: True
示例 2:

输入: flowerbed = [1,0,0,0,1], n = 2
输出: False
注意:

数组内已种好的花不会违反种植规则。
输入的数组长度范围为 [1, 20000]。
n 是非负整数,且不会超过输入数组的大小。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/can-place-flowers

class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        int sum=0;
        //记录连续0的个数
        for(int count=0,j=0;j<flowerbed.length;j++){
            if(flowerbed[j]==0){//为0时count加一
                if(j==0|j==flowerbed.length-1){//当开头和末尾为0时,种花的情况改变,00可以种1只,但当花盆不在头尾时需要000才能种1只
                    count++;//所以为了使计算公式统一,将00看成000,则需要count多加1
                }
                count++;
            }
            //当出现不为0的情况时,将前面记录的0的个数(count)计算成可种花的数量,并累加到sum
            if(flowerbed[j]!=0|j==flowerbed.length-1){
                sum+=(count-1)/2;//000为1只,00000为2只,所以推出 可种花数=(0的数量-1)
                count=0;
            }
        }
        boolean key=false;
        //特殊情况,当花盆的数量为1个时,且花盆为空时可以种一只花
        if(flowerbed.length==1&flowerbed[0]==0){
            key=true;
        }
        if(sum>=n){//当最大种花数大于想种花数n时,表示可以种
            key=true;
        }
        return key;
    }
}

581.最短无序连续子数组

给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

你找到的子数组应是最短的,请输出它的长度。

示例 1:

输入: [2, 6, 4, 8, 10, 9, 15]
输出: 5
解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
说明 :

输入的数组长度范围在 [1, 10,000]。
输入的数组可能包含重复元素 ,所以升序的意思是<=。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int left=0;
        int right=0;
        boolean flag=true;
        //先将那段无序数组的找出
            //相邻两数比较,若发现前者比后者的数大,将前者的角标用left存起来
        for(int i=1,j=0;i<nums.length;i++,j++){
            if(nums[j]>nums[i]){
                left=j;
                flag=false;
                break;
            }
        }
            //相邻两数比较,若发现前者比后者的数大,将后者的角标用right存起来
        for(int i=nums.length-2,j=nums.length-1;i>=0;i--,j--){
            if(nums[i]>nums[j]){
                right=j;
                break;
            }
        }
        //遍历nums从角标left~right,找出其中的最大值max和最小值min
        int max=nums[left],min=nums[left];
        for(int i=left;i<=right;i++){
            if(nums[i]>max){
                max=nums[i];
            }
            if(nums[i]<min){
                min=nums[i];
            }
        }
        //遍历前面一段有序的,从角标 0~left-1,让min与之比较,当出现min小于i角标的数时,说明i角标位置得放min,所以先将角标i记录到left
        for(int i=0;i<left;i++){
            if(min<nums[i]){
                left=i;
                break;
            }
        }
        //遍历后面一段有序的,从角标 最后~right-1,让max与之比较,当出现max大于i角标的数时,说明i角标位置得放max,所以先将角标i记录到right
        for(int i=nums.length-1;i>right;i--){
            if(max>nums[i]){
                right=i;
                break;
            }
        }
        //flag为判断是否整个数组有序
        //leng为所需排序的长度
        int leng=0;
        if(!flag){
            leng=right-left+1;
        }
        return leng;
    }
}

724.寻找数组的中心索引

给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。

我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。

如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

示例 1:

输入: 
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释: 
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。
示例 2:

输入: 
nums = [1, 2, 3]
输出: -1
解释: 
数组中不存在满足此条件的中心索引。
说明:

nums 的长度范围为 [0, 10000]。
任何一个 nums[i] 将会是一个范围在 [-1000, 1000]的整数。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-pivot-index

class Solution {
    public int pivotIndex(int[] nums) {
        int flag=-1;
        int sum=0;
        //将给定数组的总和求出
        for(int i=0;i<nums.length;i++){
            sum=sum + nums[i];
        }
        //特殊情况当数组的长度为0时,flag=-1。数组长度不为0时再进行计算
        if(nums.length!=0){
            int sumleft=0;
            int sumright=sum-sumleft-nums[0];
            int i=0;
            //从i=0时开始判断,当左边的数之和等于右边的数之和时,i就是中心索引,若不是,则sumleft加上i角标位置的数,sumright减去i+1后的数,再在下一轮判断i+1处是否满足中心索引
            while(true){
                if(sumleft==sumright){
                    flag=i;//找到中心索引后用flag记录,并break结束循环,flag就是最左端的中心索引
                    break;
                }
                if(i==nums.length-1){
                    break;
                }
                sumleft = sumleft+nums[i];
                sumright = sumright-nums[i+1];
                i++;
            }
        }
        return flag;
    }
}

217.存在重复元素

给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1]
输出: true
示例 2:

输入: [1,2,3,4]
输出: false
示例 3:

输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/contains-duplicate

class Solution {
    public boolean containsDuplicate(int[] nums) {
        //对nums进行排序,判断相邻的数是否相等
        //当然也要考虑排序算法时间复杂度,这里使用Arrays类中的排序算法
        Arrays.sort(nums);
        for(int i=0;i+1<nums.length;i++){
            if(nums[i]==nums[i+1]){
                return true;
            }
        }
        return false;
    }
}

35.搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:

输入: [1,3,5,6], 5
输出: 2
示例 2:

输入: [1,3,5,6], 2
输出: 1
示例 3:

输入: [1,3,5,6], 7
输出: 4
示例 4:

输入: [1,3,5,6], 0
输出: 0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-insert-position

class Solution {
    public int searchInsert(int[] nums, int target) {
        //用二分查找法来搜索位置
        int max=nums.length-1;
        int min=0;
        int mid=(max+min)/2;
        int insert=0;
        while(true){
            if(target==nums[mid]){
                return mid;
            }
            if(target>nums[mid]){
                min=mid+1;
            }else{
                max=mid-1;
            }
            if(min>max){
                if(target>nums[mid]){
                    insert=mid+1;
                }else{
                    insert=mid;
                }
                break;
            }
            mid=(max+min)/2;
        }
        return insert;
    }
}

27.移除元素

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

给定 nums = [3,2,2,3], val = 3,

函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。

你不需要考虑数组中超出新长度后面的元素。
示例 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2,

函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

注意这五个元素可为任意顺序。

你不需要考虑数组中超出新长度后面的元素。
说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element

class Solution {
    public int removeElement(int[] nums, int val) {
        /*
        因为可以打乱其他元素的顺序,所以可以在与val相同的元素用最后一个元素替换
        当替换了后,最后一个元素就失效了,让最后第二个元素成为最后一个元素
        替换后接着判断当前位置的元素与val是否相等,不相等则进行下一个索引位置进行判断    
        相等则与上述同理替换
        */
        int newlength=nums.length;
        for(int i=0;i<newlength;i++){
            if(nums[i]==val){
                nums[i]=nums[newlength-1];
                i--;
                newlength--;
            }
        }
        return newlength;
    }
}

766.托普利茨矩阵

 

如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵。

给定一个 M x N 的矩阵,当且仅当它是托普利茨矩阵时返回 True。

示例 1:

输入: 
matrix = [
  [1,2,3,4],
  [5,1,2,3],
  [9,5,1,2]
]
输出: True
解释:
在上述矩阵中, 其对角线为:
"[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]"。
各条对角线上的所有元素均相同, 因此答案是True。
示例 2:

输入:
matrix = [
  [1,2],
  [2,2]
]
输出: False
解释: 
对角线"[1, 2]"上的元素不同。
说明:

 matrix 是一个包含整数的二维数组。
matrix 的行数和列数均在 [1, 20]范围内。
matrix[i][j] 包含的整数在 [0, 99]范围内。
进阶:

如果矩阵存储在磁盘上,并且磁盘内存是有限的,因此一次最多只能将一行矩阵加载到内存中,该怎么办?
如果矩阵太大以至于只能一次将部分行加载到内存中,该怎么办?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/toeplitz-matrix

class Solution {
    public boolean isToeplitzMatrix(int[][] matrix) {
        boolean flag=true;
        /*
        将每条对角线的头元素找出,可以看出第一行都是头元素,第一列也都是头元素,并遍历它们
        在根据头元素遍历对角线上的数,判断是否与头元素相等
        */
        for(int i=0;i<=matrix[0].length-2;i++){
            for(int j=1;j<=matrix.length-1&&i+j<=matrix[j].length-1;j++){
                if(matrix[0][i]!=matrix[j][i+j]){
                    flag=false;
                    break;
                }
            }
        }
        for(int i=1;i<=matrix.length-2;i++){
            for(int j=1;j<=matrix[i].length-1&&j+i<=matrix.length-1;j++){
                if(matrix[i][0]!=matrix[j+i][j]){
                    flag=false;
                    break;
                }
            }
        }
        return flag;
    }
}

53.最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶:

如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-subarray

class Solution {
    public int maxSubArray(int[] nums) {
/*
将maxSum、newSum初始化一个元素的值
遍历nums,寻找最大的连续元素和
思路:
如果前面元素和为正,就将其与后面元素相加,如果前面元素和为负,就从后面元素开始重新累加newSum
所得的newSum与maxSum比较,使maxSum更新
*/
        int maxSum=nums[0];
        int newSum=nums[0];
        for(int i=1;i<nums.length;i++){
            if(nums[i-1]<0){
                newSum=nums[i];
            }else{
                nums[i]+=nums[i-1];
                newSum=nums[i];
            }
            if(newSum>maxSum){
                maxSum=newSum;
            }
        }
        return maxSum;
    }
}

169.多数元素

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [3,2,3]
输出: 3
示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/majority-element

class Solution {
    public int majorityElement(int[] nums) {
        int count=1;
        int thenum=nums[0];
/*
打擂台的思想:
让一个元素nums[0]上擂台
thenum为擂台上的数,count表示该数擂台上的个数
count变化规则:
    如果当前数nums[i]与thenum不同,count--;如果相同count++;
    如果count=0;则当前元素num[i]上擂台,count置为1;
    遍历完数组,超过n/2的数就会留在擂台上,也就是thenum里;
*/
        for(int i=1;i<nums.length;i++){
            if(count==0){
                thenum=nums[i];
                count=1;
            }else{
                if(nums[i]!=thenum){
                    count--;
                }else{
                    count++;
                }
            }
        }
        return thenum;
    }
}

849.到最近的人的最大距离

在一排座位( seats)中,1 代表有人坐在座位上,0 代表座位上是空的。

至少有一个空座位,且至少有一人坐在座位上。

亚历克斯希望坐在一个能够使他与离他最近的人之间的距离达到最大化的座位上。

返回他到离他最近的人的最大距离。

示例 1:

输入:[1,0,0,0,1,0,1]
输出:2
解释:
如果亚历克斯坐在第二个空位(seats[2])上,他到离他最近的人的距离为 2 。
如果亚历克斯坐在其它任何一个空位上,他到离他最近的人的距离为 1 。
因此,他到离他最近的人的最大距离是 2 。 
示例 2:

输入:[1,0,0,0]
输出:3
解释: 
如果亚历克斯坐在最后一个座位上,他离最近的人有 3 个座位远。
这是可能的最大距离,所以答案是 3 。
提示:

1 <= seats.length <= 20000
seats 中只含有 0 和 1,至少有一个 0,且至少有一个 1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximize-distance-to-closest-person

class Solution {
    public int maxDistToClosest(int[] seats) {
//借鉴 605.种花问题 的思想
        int maxDis=0;
        int newDis=0;
        int j=-1;
        for(int i=0;i<seats.length;i++){
            if(seats[i]==1){
                if(j==-1){
                    newDis=i-j-1;
                }else{
                    newDis=(i+j)/2-j;
                }
                j=i;
            }else if(seats[i]==0&&i==seats.length-1){
                newDis=i-j;
            }
            if(newDis>maxDis){
                maxDis=newDis;
            }
        }
        return maxDis;
    }
}

509.斐波那契数

斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
给定 N,计算 F(N)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fibonacci-number

class Solution {
    public int fib(int N) {
        int[] nums=new int[N+1];
        for(int i=0;i<N+1;i++){
            if(i==0){
                nums[i]=0;
            }else if(i==1){
                nums[i]=1;
            }else{
                nums[i]=nums[i-1]+nums[i-2];
            }
        }
        return nums[N];
    }
}

1160.拼写单词

给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。

假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。

注意:每次拼写时,chars 中的每个字母都只能用一次。

返回词汇表 words 中你掌握的所有单词的 长度之和。

 

示例 1:

输入:words = ["cat","bt","hat","tree"], chars = "atach"
输出:6
解释: 
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。
示例 2:

输入:words = ["hello","world","leetcode"], chars = "welldonehoneyr"
输出:10
解释:
可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10。
 

提示:

1 <= words.length <= 1000
1 <= words[i].length, chars.length <= 100
所有字符串中都仅包含小写英文字母

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters

/*
遍历chars,与words中每个单词中的字母匹配,count记录单词长度,若匹配相同则count--
count减为0时,说明该单词所有字母都匹配,sum加上该单词的长度。
为了避免与匹配成功的字母重新匹配,将匹配过的字母字符改为空格字符
由于字符串无法修改,就将字符串中存到字符数组中去,对字符数组进行操作
*/
class Solution {
    public int countCharacters(String[] words, String chars) {
        int count=0;
        int sum=0;
        for(int i=0;i<words.length;i++){
            count=words[i].length();
            //将单词从字符串的形式转化为字符数组的形式
            char[] word=new char[words[i].length()];
            for(int j=0;j<words[i].length();j++){
                word[j]=words[i].charAt(j);
            }
            //遍历chars与单词中的字母是否相等
            for(int i1=0;i1<chars.length();i1++){
                for(int j=0;j<word.length;j++){
                    //相等count--,将字母改为空格,并进行下一轮判断
                    if(chars.charAt(i1)==word[j]){
                        count--;
                        word[j]=' ';
                        break;
                    }
                }
                //count==0,说明单词所有字母全部匹配
                if(count==0){
                    sum+=words[i].length();
                    break;
                }
            }
        }
        return sum;
    }
}

994.腐烂的橘子

在给定的网格中,每个单元格可以有以下三个值之一:

值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂。

返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1。

示例 1:

输入:[[2,1,1],[1,1,0],[0,1,1]]
输出:4
示例 2:

输入:[[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。
示例 3:

输入:[[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0 。
 

提示:

1 <= grid.length <= 10
1 <= grid[0].length <= 10
grid[i][j] 仅为 0、1 或 2

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotting-oranges

class Solution {
    public int orangesRotting(int[][] grid) {
        boolean flag=false;
        boolean isfresh=false;
        int minute=0;
        //复制一份果盘
        int[][] gridLate=new int[grid.length][grid[0].length];
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[i].length;j++){
                gridLate[i][j]=grid[i][j];
            }
        }
        while(true){
            flag=false;//用flag标记是否产生了新腐烂的橘子
            for(int i=0;i<grid.length;i++){
                for(int j=0;j<grid[i].length;j++){
                    /*将已腐烂的橘子找出,并使相邻的橘子腐烂,
                    新腐烂的橘子不会当成已腐烂的橘子来操作,
                    而是通过备份,在下一轮进行操作
                    */
                    if(grid[i][j]==2){
                        if(j+1<grid[i].length&&grid[i][j+1]==1){
                            gridLate[i][j+1]=2;
                            flag=true;
                        }
                        if(j-1>=0&&grid[i][j-1]==1){
                            gridLate[i][j-1]=2;
                            flag=true;
                        }
                        if(i+1<grid.length&&grid[i+1][j]==1){
                            gridLate[i+1][j]=2;
                            flag=true;
                        }
                        if(i-1>=0&&grid[i-1][j]==1){
                            gridLate[i-1][j]=2;
                            flag=true;
                        }
                    }
                }
            }
            //判断是否有产生新腐烂的橘子
            if(flag){
                minute++;    //有,则时间加一分钟
                //将备份盘赋给操作盘
                for(int i=0;i<grid.length;i++){
                    for(int j=0;j<grid[i].length;j++){
                        grid[i][j]=gridLate[i][j];
                    }
                }
            }else{          //无,则说明不会再腐烂
                //判断是否存在新鲜橘子
                for(int i=0;i<grid.length;i++){
                    for(int j=0;j<grid[i].length;j++){
                        if(gridLate[i][j]==1){
                            isfresh=true;
                        }
                    }
                }
                if(isfresh){
                    return -1;//存在,则该橘子不会腐烂
                }else{
                    return minute;//不存在,说明所有橘子都腐烂
                }
            }
        }
    }
}

1103.分糖果II

排排坐,分糖果。

我们买了一些糖果 candies,打算把它们分给排好队的 n = num_people 个小朋友。

给第一个小朋友 1 颗糖果,第二个小朋友 2 颗,依此类推,直到给最后一个小朋友 n 颗糖果。

然后,我们再回到队伍的起点,给第一个小朋友 n + 1 颗糖果,第二个小朋友 n + 2 颗,依此类推,直到给最后一个小朋友 2 * n 颗糖果。

重复上述过程(每次都比上一次多给出一颗糖果,当到达队伍终点后再次从队伍起点开始),直到我们分完所有的糖果。注意,就算我们手中的剩下糖果数不够(不比前一次发出的糖果多),这些糖果也会全部发给当前的小朋友。

返回一个长度为 num_people、元素之和为 candies 的数组,以表示糖果的最终分发情况(即 ans[i] 表示第 i 个小朋友分到的糖果数)。

 

示例 1:

输入:candies = 7, num_people = 4
输出:[1,2,3,1]
解释:
第一次,ans[0] += 1,数组变为 [1,0,0,0]。
第二次,ans[1] += 2,数组变为 [1,2,0,0]。
第三次,ans[2] += 3,数组变为 [1,2,3,0]。
第四次,ans[3] += 1(因为此时只剩下 1 颗糖果),最终数组变为 [1,2,3,1]。
示例 2:

输入:candies = 10, num_people = 3
输出:[5,2,3]
解释:
第一次,ans[0] += 1,数组变为 [1,0,0]。
第二次,ans[1] += 2,数组变为 [1,2,0]。
第三次,ans[2] += 3,数组变为 [1,2,3]。
第四次,ans[0] += 4,最终数组变为 [5,2,3]。
 

提示:

1 <= candies <= 10^9
1 <= num_people <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/distribute-candies-to-people

class Solution {
    public int[] distributeCandies(int candies, int num_people) {
        int[] ans=new int[num_people];
        int i=0;
        while(candies>0){
            if(candies>=i+1){
                ans[i%num_people]+=i+1;
                candies-=i+1;
            }else{
                ans[i%num_people]+=candies;
                candies=0;
            }
            i++;
        }
        return ans;
    }
}

1013.将数组分成和相等的三个部分

给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。

形式上,如果可以找出索引 i+1 < j 且满足 (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1]) 就可以将数组三等分。

 

示例 1:

输出:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:

输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例 3:

输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
 

提示:

3 <= A.length <= 50000
-10^4 <= A[i] <= 10^4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum

class Solution {
    public boolean canThreePartsEqualSum(int[] A) {
        int sum=0;
        for(int i=0;i<A.length;i++){
            sum+=A[i];
        }
        if(sum%3!=0){
            return false;
        }
        int sum1=0;
        int count=0;
        for(int i=0;i<A.length;i++){
            sum1+=A[i];
            if(sum1==sum/3){
                count++;
                sum1=0;
            }
            if(count==3){
                break;
            }
        }
        return count==3;
        
    }
}

892.三维形体的表面积

在 N * N 的网格上,我们放置一些 1 * 1 * 1  的立方体。

每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。

请你返回最终形体的表面积。

 

示例 1:

输入:[[2]]
输出:10
示例 2:

输入:[[1,2],[3,4]]
输出:34
示例 3:

输入:[[1,0],[0,2]]
输出:16
示例 4:

输入:[[1,1,1],[1,0,1],[1,1,1]]
输出:32
示例 5:

输入:[[2,2,2],[2,1,2],[2,2,2]]
输出:46
 

提示:

1 <= N <= 50
0 <= grid[i][j] <= 50

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/surface-area-of-3d-shapes

class Solution {
    public int surfaceArea(int[][] grid) {
        int sum=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[i].length;j++){
                if(grid[i][j]!=0){
                    sum+=2;
                }
                if(i!=0){
                    if(grid[i][j]>=grid[i-1][j]){
                        sum+=grid[i][j]-grid[i-1][j];
                    }
                }else{
                    sum+=grid[i][j];
                }
                if(i!=grid.length-1){
                    if(grid[i][j]>=grid[i+1][j]){
                        sum+=grid[i][j]-grid[i+1][j];
                    }
                }else{
                    sum+=grid[i][j];
                }
                if(j!=0){
                    if(grid[i][j]>=grid[i][j-1]){
                        sum+=grid[i][j]-grid[i][j-1];
                    }
                }else{
                    sum+=grid[i][j];
                }
                if(j!=grid[i].length-1){
                    if(grid[i][j]>=grid[i][j+1]){
                        sum+=grid[i][j]-grid[i][j+1];
                    }
                }else{
                    sum+=grid[i][j];
                }
            }
        }
        return sum;
    }
}

999.车的可用捕获量

在一个 8 x 8 的棋盘上,有一个白色车(rook)。也可能有空方块,白色的象(bishop)和黑色的卒(pawn)。它们分别以字符 “R”,“.”,“B” 和 “p” 给出。大写字符表示白棋,小写字符表示黑棋。

车按国际象棋中的规则移动:它选择四个基本方向中的一个(北,东,西和南),然后朝那个方向移动,直到它选择停止、到达棋盘的边缘或移动到同一方格来捕获该方格上颜色相反的卒。另外,车不能与其他友方(白色)象进入同一个方格。

返回车能够在一次移动中捕获到的卒的数量。

示例 1:

输入:

[[".",".",".",".",".",".",".","."],

[".",".",".","p",".",".",".","."],

[".",".",".","R",".",".",".","p"],

[".",".",".",".",".",".",".","."],

[".",".",".",".",".",".",".","."],

[".",".",".","p",".",".",".","."],

[".",".",".",".",".",".",".","."],

[".",".",".",".",".",".",".","."]]
输出:3
解释:
在本例中,车能够捕获所有的卒。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/available-captures-for-rook

class Solution {
    public int numRookCaptures(char[][] board) {
        int x=0;
        int y=0;
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board[i].length;j++){
                if(board[i][j]=='R'){
                    x=i;
                    y=j;
                    break;
                }
            }
        }
        int count=0;
        if(x!=0){
            for(int i=x-1;i>0;i--){
                if(board[i][y]=='B'){
                    break;
                }
                if(board[i][y]=='p'){
                    count++;
                    break;
                }
            }
            
        }
        if(x!=board.length-1){
            for(int i=x+1;i<board.length;i++){
                if(board[i][y]=='B'){
                    break;
                }
                if(board[i][y]=='p'){
                    count++;
                    break;
                }
            }
        }
        if(y!=0){
            for(int i=y-1;i>0;i--){
                if(board[x][i]=='B'){
                    break;
                }
                if(board[x][i]=='p'){
                    count++;
                    break;
                }
            }
        }
        if(y!=board[x].length-1){
            for(int i=y+1;i<board[x].length;i++){
                if(board[x][i]=='B'){
                    break;
                }
                if(board[x][i]=='p'){
                    count++;
                    break;
                }
            }
        }
        return count;
    }
}

888.公平的糖果交换

爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝拥有的第 i 块糖的大小,B[j] 是鲍勃拥有的第 j 块糖的大小。

因为他们是朋友,所以他们想交换一个糖果棒,这样交换后,他们都有相同的糖果总量。(一个人拥有的糖果总量是他们拥有的糖果棒大小的总和。)

返回一个整数数组 ans,其中 ans[0] 是爱丽丝必须交换的糖果棒的大小,ans[1] 是 Bob 必须交换的糖果棒的大小。

如果有多个答案,你可以返回其中任何一个。保证答案存在。

示例 1:

输入:A = [1,1], B = [2,2]
输出:[1,2]
示例 2:

输入:A = [1,2], B = [2,3]
输出:[1,2]
示例 3:

输入:A = [2], B = [1,3]
输出:[2,3]
示例 4:

输入:A = [1,2,5], B = [2,4]
输出:[5,4]
 

提示:

1 <= A.length <= 10000
1 <= B.length <= 10000
1 <= A[i] <= 100000
1 <= B[i] <= 100000
保证爱丽丝与鲍勃的糖果总量不同。
答案肯定存在。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fair-candy-swap

class Solution {
    public int[] fairCandySwap(int[] A, int[] B) {
        int sumA=0;
        int sumB=0;
        for(int i=0;i<A.length;i++){
            sumA+=A[i];
        }
        for(int i=0;i<B.length;i++){
            sumB+=B[i];
        }
        int[] ans=new int[2];
        Arrays.sort(A);
        Arrays.sort(B);
        int i=0;
        int j=0;
        while(true){
            if(A[i]-B[j]==(sumA-sumB)/2){
                ans[0]=A[i];
                ans[1]=B[j];
                break;
            }
            if(A[i]-B[j]>(sumA-sumB)/2){
                j++;
            }else{
                i++;
            }
        }
        return ans;
    }
}

463.岛屿的周长

给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域。

网格中的格子水平和垂直方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

示例 :

输入:
[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

输出: 16

解释: 它的周长是下面图片中的 16 个黄色的边:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/island-perimeter

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值