每日leetcode - 数组 easy

88. 合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

方法:双指针加原地覆盖

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i = m-1;
        int j = n-1;
        int k = m+n-1;
        while (i>=0 && j>=0){
            if(nums1[i]<nums2[j]){
                nums1[k--] = nums2[j--];
            }else{
                nums1[k--] = nums1[i--];
            }
        }
        
        while (j>=0){
            nums1[k--] = nums2[j--];
        }
    }
}

118. 杨辉三角

给定一个非负整数 *numRows,*生成杨辉三角的前 numRows 行。在杨辉三角中,每个数是它左上方和右上方的数的和。

方法:暴力法

在这里插入图片描述

class Solution {

    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>();
        //杨辉三角的每行
        for(int i=0;i<numRows;i++){
            //每行是一个ArrayList
            List<Integer> list = new ArrayList<>();
            //每个ArrayList中存放的元素个数正好等于行数
            for(int j=0;j<=i;j++){
                //每行的第一个数和最后一个数为1
                if(j==0 || j==i) {
                    list.add(1);
                }else{
                    //每行的其他数为是它左上方和右上方的数的和
                    list.add(res.get(i-1).get(j)+res.get(i-1).get(j-1));
                }
            }
            res.add(list);
        }
        return res;
    }
}

121. 买卖股票的最佳时机

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。注意:你不能在买入股票前卖出股票。

方法:动态规划

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length==0 || prices==null) return 0;
        // dp[i][j]代表第i天股票状态为j时,所能获得的最大利润
        // j=0:买入股票,j=1:卖出股票
        int[][] dp = new int[prices.length][2];
        dp[0][0] =-prices[0];
        dp[0][1] = 0;
        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][0],-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
        }
        return dp[prices.length-1][1];
    }
}

122. 买卖股票的最佳时机 II

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

方法:动态规划

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length==0 || prices==null) return 0;
        //dp[i][j]代表第i天股票状态为j时,所能获得的最大利润
        // j=0:买入股票,j=1:卖出股票
        int[][] dp = new int[prices.length][2];
        dp[0][0] =-prices[0];
        dp[0][1] = 0;
        for(int i=1;i<prices.length;i++){
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
        }
        return dp[prices.length-1][1];
    }
}

167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

方法:双指针

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int index1 = 0;
        int index2 = numbers.length-1;
        while (index1<index2){
            if(numbers[index1]+numbers[index2]==target){
                return new int[]{index1+1,index2+1};
            }else if(numbers[index1]+numbers[index2]<target){
                index1++;
            }else{
                index2--;
            }
        }
        return new int[]{-1,-1};
    }
}

169. 多数元素

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。

class Solution {
    public int majorityElement(int[] nums) {
        int count = 0;
        int mainNum = 0;
        for(int i=0;i<nums.length;i++){
            //如果count==0就更新众数
            if(count==0){
                mainNum = nums[i];
            }
            if(nums[i]==mainNum){
                count++;
            }else{
                count--;
            }
        }
        return mainNum;
    }
}

217. 存在重复元素

给定一个整数数组,判断是否存在重复元素。如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false

方法:先排序,排序后判断存不存在前后两个数相同,存在就返回true,不存在就返回false

class Solution {
    public boolean containsDuplicate(int[] nums) {
        if(nums.length==0 || nums==null) return false;
        Arrays.sort(nums);
        for(int i=1;i<nums.length;i++){
            if(nums[i] == nums[i-1]){
                return true;
            }
        }
        return false;
    }
}

219. 存在重复元素 II

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

方法1:暴力法

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length;j++){
                if(nums[i]==nums[j] &&j-i<=k){
                    return true;
                }
            }
        }
        return false;
    }
}

方法2:使用HashSet维持一个长度为k的窗口

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        HashSet<Integer> set = new HashSet<>();
        //维持一个长度为k的窗口
        for(int i=0;i<nums.length;i++){
            if(set.contains(nums[i])) return true;
            set.add(nums[i]);
            //如果set集合的长度大于k,移除set集合中最旧的那个元素
            if(set.size()>k){
                set.remove(nums[i-k]);
            }
        }
        return false;
    }
}

268. 丢失的数字

给定一个包含 [0, n]n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

方法1:先排序,然后看元素下标和元素是否相同,如果不同,就返回数组下标,如果循环结束扔相同,返回n

class Solution {
    public int missingNumber(int[] nums) {
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            //[0,1,2,4]
            if(nums[i]!=i) return i;
        }
        //[0,1]
        return nums.length;
    }
}

方法2:哈希表,将数组中元素都存进hash表中,然后判断[0-n]中的元素哪个没在hash表中

class Solution {
    public int missingNumber(int[] nums) {
        HashSet<Integer> set = new HashSet<>();
        for(int i=0;i<nums.length;i++){
            set.add(nums[i]);
        }
        for(int i=0;i<=nums.length;i++){
            if(!set.contains(i)){
                return i;
            }
        }
        return -1;
    }
}

方法3:位运算

class Solution {
    public int missingNumber(int[] nums) {
         //异或运算,先把[0,n]之间的数进行位运算,然后在于数组nums中的元素进行位运算,即为最终结果
         //比如[0,1,2,4] 先把0^1^2^3^4 再^0^1^2^4 = (0^0)^(1^1)^(2^2)^(4^4)^3=3
        int count = nums.length;
        for(int i=0;i<nums.length;i++){
            count = count ^ i;
        }
        for(int i=0;i<nums.length;i++){
            count = count ^ nums[i];
        }
        return count;
    }
}
已标记关键词 清除标记
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页