LeetCode初级算法书Java题解日常更新

LeetCode初级算法高效题解(含思路注释)



前言

决定用四个月过一下算法


一、数组

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

>给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

class Solution {
    public int removeDuplicates(int[] nums) {
        int left=0;
        //请你 原地 删除重复出现的元素,使每个元素 只出现一次 
        for(int right=1;right<nums.length;right++){
            //如果右等于左,左不变,右加一
            if(nums[right]!=nums[left]){
                //左指针先往前再赋值
                left++;
                nums[left]=nums[right];
            }
        }
        return left+1;
    }
}

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

代码如下(示例):

class Solution {
    public int maxProfit(int[] prices) {
        int sum=0;
        //本题即求无序数组的最大值与最小值的差
        for(int i=0;i<prices.length-1;i++){//注意length-1这里外层循环遍历到倒数第二个即可
            if(prices[i+1]>prices[i]){//如果后一个大于前一个则把两者差值存进sum
            sum+=prices[i+1]-prices[i];//两两前后遍历的差值和即为最低值与最高值的差值
            }
        }
        return sum;
    }
}

3.旋转数组

在这里插入图片描述

class Solution {
    public void rotate(int[] nums, int k) {
      int length=nums.length;
      int[] tem=new int[length];
      //先用临时数组存原数组方便后边原数组存值
      for(int i=0;i<length;i++){
          tem[i]=nums[i];
      }
      //用i与偏移量k两者和去取余数组长度,得到偏移后的位置
      for(int i=0;i<length;i++){
          nums[(i+k)%length]=tem[i];
      }
    }
}

4.存在重复元素

在这里插入图片描述

class Solution {
    public boolean containsDuplicate(int[] nums) {
        Set<Integer> set=new HashSet<>();//hashSet重复元素不可插入
        for(int i=0;i<nums.length;i++){
            //hashSet.add如果返回false则说明有重复元素插入
           if(!set.add(nums[i])){
              return true;
           }
        }
        return false;
    }
}

5.只出现一次的数字

在这里插入图片描述

class Solution {
    public int singleNumber(int[] nums) {
        //使用异或运算抓取出现次数为1的数组元素
        int flag=0;
        //使用异或运算两种特性
        //第一点任何数与0异或等于它本身,
        //第二点自己与自己异或等于0
        //第三点异或运算支持分配律即可以更换运算位置
        //综上可知:例如nums[1,1,2] 1^1^2=2,即2为出现一次的元素
        for(int num:nums){
            flag^=num;
        }
        return flag;
    }
}

6.两个数组的交集 II

在这里插入图片描述

class Solution {
    public int[] intersect(int[] nums1, int[] nums2) {
        // 先对两个数组进行排序
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i = 0;
        int j = 0;
        List<Integer> list = new ArrayList<>();
        while (i < nums1.length && j < nums2.length) {
            if (nums1[i] < nums2[j]) {
                // 如果i指向的值小于j指向的值,,说明i指向
                // 的值小了,i往后移一步
                i++;
            } else if (nums1[i] > nums2[j]) {
                // 如果i指向的值大于j指向的值,说明j指向的值
                // 小了,j往后移一步
                j++;
            } else {
                // 如果i和j指向的值相同,说明这两个值是重复的,
                // 把他加入到集合list中,然后i和j同时都往后移一步
                list.add(nums1[i]);
                i++;
                j++;
            }
        }
        //把list转化为数组
        int index = 0;
        int[] res = new int[list.size()];
        for (int k = 0; k < list.size(); k++) {
            res[index++] = list.get(k);
        }
        return res;
    }

}

8.加一

在这里插入图片描述

class Solution {
    public int[] plusOne(int[] digits) {
        int end=digits.length-1;
        //尾部指针,遍历所有数,如果遍历数为9就进入调整数组
        while(digits[end]==9){
            digits[end]=0;
            if(end==0){
                //数组扩容
                digits=Arrays.copyOf(digits,digits.length+1);
                //循环后移一位
                for(int i=digits.length-1;i>0;i--){
                    digits[i]=digits[i-1];
                }
                //第一位设置为1(例如999+1=1000)
                digits[0]=1;
                return digits;
            }
            end--;
        }
        //如果不为9直接加一即可
        digits[end]++;
        return digits;
        
    }
}

9.移动零

在这里插入图片描述

class Solution {
    public void moveZeroes(int[] nums) {//涉及对原数组直接操作的直接用双指针
        int left=0;//左指针负责存正确遍历数到指定位置
        for(int right=0;right<nums.length;right++){
            if(nums[right]!=0){
                nums[left]=nums[right];//遍历数不为0,则左指针指向的位置进行赋值遍历数
                left++;
            }
        }
        for(int j=left;j<nums.length;j++){//剩下的都是因为遍历到0由于数组元素左移而空出来的位置
             nums[j]=0;//多出来的数组位置直接赋值0
        }
    }
}

10.两数之和

在这里插入图片描述

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        int[] ans = new int[2];
        for(int i=0; i<nums.length; i++){
            if(map.containsKey(target - nums[i])){  //判断另一个数在不在map里,在的话就输出位置序列
                    ans[0] = map.get(target - nums[i]);
                    ans[1] = i;
                    break;
            }else{//另一个数不在map里则先存进map,继续遍历后面数,让target去减遍历数得到另一个数,
                //判断差值与看前面存的数是否相等
                    map.put(nums[i], i);//key为已遍历数,value为位置序列
                }
        }
        return ans;
    }
}

11.反转字符串

在这里插入图片描述

class Solution {
    public void reverseString(char[] s) {
            int right=s.length-1;
        char[] temp=Arrays.copyOf(s,s.length);//用临时数组存原来的数组
        for(int left=0;left<s.length;left++){//遍历原数组,挨个进行重新赋值
            s[left]=temp[right];//逆序输出临时数组值到原数据上
            right--;
        }
    }
}

12.整数反转

在这里插入图片描述

class Solution {
        public int reverse(int x) {
        long res = 0;
        while (x != 0) {
            res = res * 10 + x % 10;//返回取余数乘以10与新一位取余数的和
            x /= 10;//对x进行除10来得到x上的数字(除了个位数),目的是方便后面取余遍历单个数字
        }
        return (int) res == res ? (int) res : 0;
    }

}

13.字符串中的第一个唯一字符

在这里插入图片描述

class Solution {
    public int firstUniqChar(String s) {
        for(int i=0;i<s.length();i++){
            //(s.indexOf从字符窜前面遍历到后面找一个元素,找到返回索引找不到返回-1
            //(s.lastIndexOf同理不过是从后往前找的,找到返回索引找不到返回-1
            if(s.indexOf(s.charAt(i))==s.lastIndexOf(s.charAt(i))){
                return i;
            }
        }
        return -1;
    }
}

14.有效的字母异位词

在这里插入图片描述

class Solution {
    public boolean isAnagram(String s, String t) {
        //对两字符窜进行排序
        char[] s1=s.toCharArray();
        char[] t1=t.toCharArray();
        //相同的会排序在一起
         Arrays.sort(s1);
        Arrays.sort(t1);
        //最后进行判断即可
        return Arrays.equals(s1, t1);
    }
}

总结

这个月先过一遍基础算法,后边再做打算。
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值