leetcode刷题记录

本文是小菜鸡的练习记录,参考了大佬的笔记 https://leetcode.wang/leetCode-1-Two-Sum.html

一、两数之和 two sum

解法一:暴力解法两层循环

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int []ans=new int[2];
        for(int i = 0; i < nums.length; i++){
            for(int j = 0;j<nums.length; j++){
                if(nums[i] + nums[j] == target){
                    ans[0] = i;
                    ans[1] = j;
                    return ans;
                }
            }
        }
        return ans;
    }
}

没想到的点:返回值用一个数组放置。首先定义一个ans[2],之后用它来返回下标。

解法二:对第二层循环进行改进

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int []ans=new int[2];
        for(int i = 0; i < nums.length; i++){
        // 这里将j初始值设为i+1,因为[i,i-1]的组合已经在i = i-1的时候遍历过了,所以可以直接从j = i+1开始
            for(int j = (i + 1);j<nums.length; j++){
                if(nums[i] + nums[j] == target){
                    ans[0] = i;
                    ans[1] = j;
                    return ans;
                }
            }
        }
        return ans;
    }
}

解法三:对if判断语句做变化

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int []ans=new int[2];
        for(int i = 0; i < nums.length; i++){
            for(int j = (i + 1);j<nums.length; j++){
            // 这里进行改变,不求和判断了,改成理应的差值与nums[j]作比较
                int sub = target - nums[i];
                if( nums[j] == sub){
                    ans[0] = i;
                    ans[1] = j;
                    return ans;
                }
            }
        }
        return ans;
    }
}

解法四:使用hashmap

将数组中的值作为key,将下标作为value

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            map.put(nums[i],i);
        }
        for(int j = 0;j < nums.length; j++){
            int sub = target - nums[j];
            // 这里要注意排除掉某个数本身,因为同一个数不能使用两次
            if( map.containsKey(sub) && map.get(sub) != j){
                return new int[]{j,map.get(sub)};
            }
        }
        return null;
    }
}

解法五:想不到

这个解法把解法四的循环合二为一,并且没有想到可以将map.put放在if语句后面。
这样可以不用判断满足条件的是否为当前元素的情况,因为当前元素还没有被放进map里。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            int sub = target - nums[i];
            if(map.containsKey(sub)){
                return new int[]{map.get(sub),i};
            }
            map.put(nums[i],i);
        }
        return null;
    }
}

二、 长度为三且各字符不同的子字符串(1876)

解法一:暴力解法

class Solution {
    public int countGoodSubstrings(String s) {
        int num = 0;
        // 一开始出错在这里的length-2 因为是"i<" 取不到length-3,所以要改成减二
        for(int i = 0;i < s.length() - 2;i++){
            String zi = s.substring(i,i+3);
            if(zi.charAt(0) != zi.charAt(1) && zi.charAt(0) != zi.charAt(2) && zi.charAt(1) != zi.charAt(2)){
                num += 1;
            }
        }
        return num;
    }
}

总结:①字符串取其中的某几个字符的方法:“asdfghj”.substring(1,5)取的是"sdfg".左闭右开.可参考 https://blog.youkuaiyun.com/billxin0621/article/details/98485271
②取字符串中某一个位置的字符,用s.charAt()
在这里插入图片描述

参考http://www.qidianbaike.com/post/49102.html

三、设计停车系统(1603)

参考:https://www.pudn.com/news/6254433347503a0a93a3fb73.html

解法一:暴力解法

// 首先是一个停车场类
class ParkingSystem {
    int big,medium,small;
    
    //在 ParkingSystem类中实现big,medium,small的初始化
    public ParkingSystem(int big, int medium, int small) {
        this.big = big;
        this.medium = medium;
        this.small = small;
    }
    
		//判断停车场内是否有余位置
    public boolean addCar(int carType) {
        if(carType == 1){
            if(big > 0){
                big --;
                return true;
            }else{
                return false;
            }
        }else if(carType == 2){
            if(medium > 0){
                medium --;
                return true;
            }else{
                return false;
            }
        }else if(carType == 3){
            if(small > 0){
                small --;
                return true;
            }else{
                return false;
            }
        }
    return true;
    }
}

方法二:简化方法一

去掉了FALSE判断,但是最后这里要改成return false

class ParkingSystem {
    int big,medium,small;
    public ParkingSystem(int big, int medium, int small) {
        this.big = big;
        this.medium = medium;
        this.small = small;
    }
    
    public boolean addCar(int carType) {
        if(carType == 1){
            if(big > 0){
                big --;
                return true;
            }
        }else if(carType == 2){
            if(medium > 0){
                medium --;
                return true;
            }
        }else if(carType == 3){
            if(small > 0){
                small --;
                return true;
            }
        }
    return false;
    }
}

四、执行操作后的变量值

解法一:暴力解法

class Solution {
    public int finalValueAfterOperations(String[] operations) {
        int x = 0;
        for(int i = 0; i < operations.length; i++){
        // 这里一开始用的“==”,结果不对才想到用equals 
            if( "--X".equals(operations[i]) || "X--".equals(operations[i])){
                x -= 1;
            }else if("++X".equals(operations[i]) || "X++".equals(operations[i])){
                x += 1;
            }
        }
        return x;
    }
}

总结:equals和==用法区别:一个是指内存地址 一个指值
在这里插入图片描述String s=“abcd"是一种非常特殊的形式,和new 有本质的区别。它是java中唯一不需要new 就可以产生对象的途径。以String s=“abcd”;形式赋值在java中叫直接量,它是在常量池中而不是象new一样放在压缩堆中。 这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"abcd"的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象, 如果没有,则在常量池中新创建一个"abcd”,下一次如果有String s1 = “abcd”;又会将s1指向"abcd"这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象.

参考:https://blog.youkuaiyun.com/qq_44580803/article/details/123556176

五、基于排列构建数组(1920)

解法一:暴力解法

class Solution {
    public int[] buildArray(int[] nums) {
        int length = nums.length;
        int[] ans = new int[length];
        for(int i = 0; i < length;i++){
            ans[i] = nums[nums[i]];
        }
        return ans;
    }
}

六、 回文数(9.)

解法一:暴力解法,将int转换成string判断字符串是否相等

class Solution {
    public boolean isPalindrome(int x) {
    // 先将x转换成字符串
        String s = String.valueOf(x);
        // 准备一个空string 用来放倒置之后的字符串
        String t = "";
        // 倒置拼接
        for(int i = s.length()-1;i >= 0; i--){
            t += s.charAt(i);
        }
        if(t.equals(s)){
            return true;
        }else{
            return false;
        }
    }
}

缺点:运行效率低

解法二:大佬的妙思

class Solution {
    public boolean isPalindrome(int x) {
        if (x == 0) return true;
        if (x < 0 || x % 10 == 0) return false;
        int reversed = 0;
        while (x > reversed) {
            reversed = reversed * 10 + x % 10;
            x /= 10;
        }
        // 这里还没看明白
        return x == reversed || x == reversed / 10;
    }
}

解法三:Java流氓写法(调用api)(也是评论区大佬写的)

这个reverse()用的就很牛

public boolean isPalindrome(int x) {
        return new StringBuilder(String.valueOf(x)).reverse().toString().equals(String.valueOf(x));
}

七、 删除有序数组中的重复项(26.)

解法一:直接抄solution,加上自己的理解默写

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

八、 移除元素(27.)

解法一:暴力解法

class Solution {
    public int removeElement(int[] nums, int val) {
        int a = 0;
        for(int i = 0;i < nums.length;i++){
            if(nums[i] != val){
                nums[a] = nums[i];
                a++;
            }
        }
        return a;
    }
}

解法二:大佬解法,fast slow指针,本质思想和俺的差不多

class Solution {
    public int removeElement(int[] nums, int val) {
        int fast = 0;
        int slow = 0;
        while(fast != nums.length){
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
}

解法三:大佬解法,一个正向指针一个反向

class Solution {
    public int removeElement(int[] nums, int val) {
    // 对n的取值,要小心是length还是length-1
        int n = nums.length;
        int i = 0;
        while(i < n){
            if(nums[i] == val){
                nums[i] = nums[n-1];
                n--;
            }else{
                i++;
            }
        }
        return n;
    }
}

九、 加一(66.)

方法一:抄的大佬的解法

很少用到这种自定义方法,要背过这个!!

class Solution {
    public int[] plusOne(int[] digits) {
        return plusOneAtIndex(digits,digits.length - 1);
    }

    private int[] plusOneAtIndex(int[] digits,int index){
    // 考虑[9]的情况 要扩展。
        if(index < 0){
            int[] ans = new int[digits.length + 1];
            ans[0] = 1;
            return ans;
        }
			// 如果这个位置<9即可直接加一,返回值就行
        if(digits[index] < 9){
            digits[index] ++;
            return digits;
        }
        // 否则的话这个位置赋值0
        digits[index] = 0;
        
        // 这里相当于循环了,重复代值
        return plusOneAtIndex(digits, index - 1);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值