leetcod打卡

2020/4/17

明天开始每日打卡计划

数组专题 simple

1

485. 最大连续1的个数

给定一个二进制数组, 计算其中最大连续1的个数。

示例 1:

输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
思路:记录连续的个数,遇到0将计数清零

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int cnt = 0;
        int max=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==1){
                cnt++;
                max=Math.max(max,cnt);
            }else{
                cnt=0;
            }
        }
        return max;
    }
}

2

219. 存在重复元素 II

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。

示例 1:

输入: nums = [1,2,3,1], k = 3
输出: true
利用map的性质,若没有的数字将其放入字典中,否则取出比较距离,若符合则返回true,否则将当前的索引放入字典中,循环结束返回false;

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            int tmp = nums[i];
            if(map.containsKey(tmp)){
                int index=map.get(tmp);
                if(i-index<=k)
                return true;
                map.put(tmp,i);
            }else{
                map.put(tmp,i);
            }
        }
        return false;
    }
}

3

643. 子数组最大平均数 I

给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数。

示例 1:

输入: [1,12,-5,-6,50,3], k = 4
输出: 12.75
解释: 最大平均数 (12-5-6+50)/4 = 51/4 = 12.75

思路:维护一个sum,初始化为前k个数字的和,求agv,然后从下标从k开始遍历,每次加上nums[i]-nums[i-k];取最大值,

class Solution {
    public double findMaxAverage(int[] nums, int k) {
        int n = nums.length;
        int sum = 0;
        double ans = 0;
        for(int i=0;i<k;i++){
            sum+=nums[i];
        }
        ans = sum*1.0/k;
        for(int i=k;i<n;i++){
            sum+=nums[i]-nums[i-k];
            ans=Math.max(ans,(sum*1.0/k));
        }
        return ans;
    }
}

4

605. 种花问题

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

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

示例 1:

输入: flowerbed = [1,0,0,0,1], n = 1
输出: True
思路:本题主要是要处理边界问题比较麻烦,如果数组长度为1,那么直接判断结果,否则先处理左边,如果如果边界为0,并且第二个位子为0,那么计数加1,否则,将索引直接加1,

class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        int index = 0;
        int ans = 0;
        int len = flowerbed.length;
        if(len==1){
            if(flowerbed[0]==0)
            ans++;
            return ans>=n;
        }
        while(index<len&&flowerbed[index]==1){
            index++;
        }
        if(index==0&&flowerbed[1]==0){
            flowerbed[0]=1;
            ans++;
            
        }
        index++;
            for(int i=index;i<len-1;i++){
                if(flowerbed[i]==0&&flowerbed[i-1]==0&&flowerbed[i+1]==0){
                    flowerbed[i]=1;
                    ans++;
                }
            }
        if(flowerbed[len-1]==0&&flowerbed[len-2]==0)
        ans++;    
        return ans>=n;

        
    }
}

5

674. 最长连续递增序列

给定一个未经排序的整数数组,找到最长且连续的的递增序列。

示例 1:

输入: [1,3,5,4,7]
输出: 3
解释: 最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在原数组里被4隔开。

比较简单

class Solution {
    public int findLengthOfLCIS(int[] nums) {
        if(nums.length==0)
        return 0;
        int cnt=1;
        int max = 1;
        for(int i=1;i<nums.length;i++){
            if(nums[i]>nums[i-1]){
                cnt++;
                max=Math.max(cnt,max);
            }else{
                cnt=1;
            }
        }
        return max;
    }
}

6

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

给你一个数组 arr ,请你将每个元素用它右边最大的元素替换,如果是最后一个元素,用 -1 替换。

完成所有替换操作后,请你返回这个数组。

示例:

输入:arr = [17,18,5,4,6,1]
输出:[18,6,6,6,1,-1]

class Solution {
    public int[] replaceElements(int[] arr) {
        int n = arr.length;
        int[] ans = new int[n];
        ans[n-1]=-1;
        int max = arr[n-1];
        for(int i=n-2;i>=0;i--){
            ans[i]=max;
            max=Math.max(max,arr[i]);
        }
        return ans;
    }

}

7

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 的倍数则直接输出false;否则遍历数组求和,当和为0的时候计数加1,结束以后判断计数是否大于等于3;是的话返回true;

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 agv = sum/3;
        int cnt = 0;
        int tmp =Integer.MIN_VALUE;
        for(int i=0;i<A.length;i++){
            if(tmp==Integer.MIN_VALUE){
                tmp=0;
                tmp+=A[i];
            }else{
                tmp+=A[i];
            }

            if(tmp==agv){
                tmp=Integer.MIN_VALUE;
                cnt++;
            }

        }
        return cnt>=3;
    }
}

8

414. 第三大的数

给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。

示例 1:

输入: [3, 2, 1]

输出: 1

解释: 第三大的数是 1.

思路:用三个变量来存放第一大,第二大,第三大的元素的变量,分别为one, two, three;
遍历数组,若该元素比one大则往后顺移一个元素,比two大则往往后顺移一个元素,比three大则赋值个three;
最后得到第三大的元素,若没有则返回第一大的元素。

class Solution {
    private long MIN = Long.MIN_VALUE;    // MIN代表没有在值
    
    public int thirdMax(int[] nums) {
        if (nums == null || nums.length == 0) throw new RuntimeException("nums is null or length of 0");
        int n = nums.length;
        
        int one = nums[0];
        long two = MIN;
        long three = MIN;
        
        for (int i = 1; i <  n; i++) {
            int now = nums[i];
            if (now == one || now == two || now == three) continue;    // 如果存在过就跳过不看
            if (now > one) {
                three = two;
                two = one;
                one = now;
            } else if (now > two) {
                three = two;
                two = now;
            } else if (now > three) {
                three = now;
            }
        }

        if (three == MIN) return one;  // 没有第三大的元素,就返回最大值
        return (int)three;
    }
}

9

566. 重塑矩阵

在MATLAB中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据。

给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的行遍历顺序填充。

如果具有给定参数的reshape操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

示例 1:

输入:
nums =
[[1,2],
[3,4]]
r = 1, c = 4
输出:
[[1,2,3,4]]
解释:
行遍历nums的结果是 [1,2,3,4]。新的矩阵是 1 * 4 矩阵, 用之前的元素值一行一行填充新矩阵。

思路:先判断前后的总个数是否相等,即转换前后的行列乘积

class Solution {
    public int[][] matrixReshape(int[][] nums, int r, int c) {
        int row =nums.length;
        int col=0;
        if(row!=0)
         col = nums[0].length;
        if(row*col!=r*c)
        return nums;
        int aa = 0;
        int bb = 0;
        int[][] ans = new int[r][c];
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                ans[i][j]=nums[aa][bb];
                bb++;
                if(bb%col==0){
                    bb=0;
                    aa++;
                }
            }
        }
        return ans;
    }
}

10

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

给你一个整数数组 nums,请你返回其中位数为 偶数 的数字的个数。

示例 1:

输入:nums = [12,345,2,6,7896]
输出:2
解释:
12 是 2 位数字(位数为偶数)
345 是 3 位数字(位数为奇数)
2 是 1 位数字(位数为奇数)
6 是 1 位数字 位数为奇数)
7896 是 4 位数字(位数为偶数)
因此只有 12 和 7896 是位数为偶数的数字

class Solution {
    public int findNumbers(int[] nums) {
        int len = nums.length;
        int ans  = 0;
        for(int i=0;i<len;i++){
            int tmp = nums[i];
            int cnt = 0;
            while(tmp>0){
                cnt++;
                tmp=tmp/10;
            }
            if((cnt&1)==0)
            ans++;
        }
        return ans;
    }
}
发布了4 篇原创文章 · 获赞 0 · 访问量 17

猜你喜欢

转载自blog.csdn.net/smile_study1/article/details/105589199