leetcode题解:数组


🏚1.删除排序数组中的重复项

在这里插入图片描述
解题思路 使用双指针,首先题目中数组是已经排好顺序的,i为慢指针,j为快指针,如果nums[i]=nums[j]跳过重复项,直到nums[i]!=nums[j],跳过与 i 重复的所有元素,将nums[j]赋值给 i 的下一位nums[i+1],然后递增i,j继续跳过当前 i 的重复项。

代码

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

🏚2.买卖股票的最佳时机

在这里插入图片描述
解题思路 将数组中的数字绘制成表格
在这里插入图片描述
分析可得,我们需要得到所有的峰值和谷值,最后加起来得到最大利润。因为因为 C 总是小于 A+B

公式:在这里插入图片描述代码

class Solution {
    public int maxProfit(int[] prices) {
        int i=0;
        //定义谷点
        int valley = prices[0];
        //定义峰点
        int peak = prices[0];
        //最大利润
        int maxmoney = 0;
        
        while(i<prices.length-1){
            //找到谷点
            while(i<prices.length-1&&prices[i]>=prices[i+1]){i++;}
            //得到谷点
            valley = prices[i];
            //寻找峰点
            while(i<prices.length-1&&prices[i]<=prices[i+1]){i++;}
            //得到峰点
            peak = prices[i];
            maxmoney+=peak-valley;
        }
        return maxmoney;
    }
}

🏚3.存在重复元素

在这里插入图片描述
解题思路 使用set数组的contains()函数判断传入的key是否出现两次,出现第二次直接返回true

代码

class Solution {
    public boolean containsDuplicate(int[] nums) {
     HashSet<Integer> set=new HashSet<Integer>();
        for(int i=0;i<nums.length;i++){
            if(set.contains(nums[i])){return true;}
            else{set.add(nums[i]);}
        }
        return false;
    }
}

🏚4.只出现一次的数字

在这里插入图片描述
解题思路 首先考虑使用map,遍历一遍数组,将数组的值作为key存入map中,得到value等于1。
更简单的是利用所有数进行异或运算,得到的值为所求的。

代码

class Solution {
    public int singleNumber(int[] nums) {
       int result=0;
       for(int i=0;i<nums.length;i++){
           result=result^nums[i];
       } 
        return result;
    }
}

🏚5.两个数组的交集 II

在这里插入图片描述
解题思路 首先将两个数组中较小的数组存入一个map中,key为数组的元素,value为出现的次数。遍历第二个数组,如果map内存在遍历元素的key,且次数大于1,则将该元素存入结果集中(可以用数组1作为结果集),map内该元素的value减一。

代码

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        Map<Integer,Integer> map=new HashMap<>();
      for (int i = 0; i <nums1.length ; i++) {
            if(map.get(nums1[i])==null){
                map.put(nums1[i],1);
            }else{
                map.put(nums1[i],map.get(nums1[i])+1);
            }
        }
        int k=0;
        for (int i = 0; i <nums2.length ; i++){
            if(map.get(nums2[i])!=null){
                if(map.get(nums2[i])>0){
                nums1[k++]=nums2[i];
                map.put(nums2[i],map.get(nums2[i])-1);}
            }
        }
        return  Arrays.copyOfRange(nums1, 0, k);
}}

🏚6.移动零

在这里插入图片描述
解题思路 用双指针,fast指针找不为0的数字,slow指针用来将fast指针找到的数字移动到前面去,最后再last指针的位置加上(fast-last)个0可得。

代码

class Solution {
    public void moveZeroes(int[] nums) {
        if(nums.length==0||nums.length==1){return;}
         int fast=0;
         int slow=0;
       while(fast<nums.length){
           while(nums[fast]==0&&fast<nums.length-1){
               fast++;
           } 
          nums[slow]=nums[fast];
           slow++;
           fast++;
       }
       for(int i=0;i<(fast-slow);i++){
           nums[slow+i]=0;
       }  
    }
}

🏚7.有效的数独

在这里插入图片描述
解题思路 分析题目可以得到题目隐含条件:每一行不能出现重复数字,每一列不能出现重复数字,每一个3*3宫格不能出现重复数字,共有九行,九列,九宫格。
我们给每一行,每一列,每一宫格都定义一个map。遍历整个大数组,将当前数字分别放入当前数字所在的行,列,宫格的map中。
判断map中当前数字是否出现过,如果出现过直接返回false,否则返回true。

代码

class Solution {
    public boolean isValidSudoku(char[][] board) {
    //遍历一遍,首先定义3*9个map 每一行一个(九行),每一列一个(九列),每一宫格一个(九宫格)
    HashMap<Integer, Integer> [] rows = new HashMap[9];
    HashMap<Integer, Integer> [] columns = new HashMap[9];
    HashMap<Integer, Integer> [] boxes = new HashMap[9];
        
     for(int i=0;i<9;i++){
         rows[i]=new HashMap<Integer, Integer>();
         columns[i]=new HashMap<Integer, Integer>();
         boxes[i]=new HashMap<Integer, Integer>();
     }
        
        for(int i=0;i<9;i++){//遍历每一行
            for(int j=0;j<9;j++){//遍历每一列
               char num=board[i][j];//取得当前数字
                if(num!='.'){//如果有数字
                    int n=(int)num;
                    int box_index = (i / 3 ) * 3 + j / 3;//根据公式求得当前数字所在的宫格序号
                    rows[i].put(n,rows[i].getOrDefault(n, 0)+1);//将n放入第i行的map中,如果存在则加1   
                    columns[j].put(n,columns[j].getOrDefault(n, 0)+1);//将n放入第j列的map中,如果存在则加1 
                    boxes[box_index].put(n,boxes[box_index].getOrDefault(n, 0)+1);//将n放入序号为box_index宫格的map中,如果存在则加1 
                
                   if(rows[i].get(n)>1||columns[j].get(n)>1||boxes[box_index].get(n)>1){return false;}
                }
            }
        }
      return true;//遍历完成
    }
}

🏚8.旋转图像

在这里插入图片描述
解题思路 观察可得,旋转矩阵=转置矩阵(行变为列)+翻转矩阵

代码

class Solution {
    public void rotate(int[][] matrix) {
          //先将矩阵转置,在翻转矩阵
        int n=matrix.length;
        //转置,将矩阵右上方的元素与右下方交换
        for(int i=0;i<n;i++){
            for(int j=i;j<n;j++){
                int temp=matrix[i][j];
                matrix[i][j]=matrix[j][i];
                matrix[j][i]=temp;
            }
        }
        //翻转,轴对称旋转
        for(int i=0;i<n;i++){
            for(int j=0;j<n/2;j++){
                int temp=matrix[i][j];
                matrix[i][j]=matrix[i][n-1-j];
               matrix[i][n-1-j]=temp;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值