双非本科准备秋招(10.1)—— 力扣刷题

1、18. 四数之和

难点还是在于去重。

借鉴之前做的三数之和的思路,三数之和是一层循环,两个指针。

那么这个题就可以两层循环,两个指针。

这题和三数之和有什么区别呢?三数之和是判断和是否为0,这个题是判断和是否为target,那么就不能简单地认为nums[i]>0就break了。因为可能是例如-4 -1 0 0,target=-5这种情况。所以剪枝的时候必须要求target>0,nums[i]>target才行。

剩下的就没啥区别了。

class Solution {
    public List> fourSum(int[] nums, int target) {
        ArrayList list = new ArrayList<>();
        int m = 0, n = 0;
        Arrays.sort(nums);
        for(int i = 0; i < nums.length-2; i++){
            //第一层剪枝
            if(nums[i] > target && target > 0) break;
            //第一层去重
            if(i > 0 && nums[i] == nums[i-1]) continue;
            for(int j = i+1; j < nums.length-1; j++){
                //第二层剪枝
                if(nums[i]+nums[j] > target && target > 0) break;
                //第二层去重
                if(j > i+1 && nums[j] == nums[j-1]) continue;
                m = j+1;
                n = nums.length-1;
                while(m < n){

                    if((long)nums[i]+nums[j]+nums[m]+nums[n] > target){
                        n--;
                    }
                    else if((long)nums[i]+nums[j]+nums[m]+nums[n] < target){
                        m++;
                    }
                    else{
                        list.add(List.of(nums[i], nums[j], nums[m], nums[n]));
                        while(mm && nums[n] == nums[n-1]) n--;
                        m++;
                        n--;
                    }
                }
            }
        }
        return list;
    }
}

2、344. 反转字符串

水题。

双非本科准备秋招(10.1)—— 力扣刷题_第1张图片

经典做法:只需要遍历字符串长度的一半,然后计算一下当前字符对应后半部分是哪个字符,交换二者即可,从图中看出,和奇偶无关。

class Solution {
    public void reverseString(char[] s) {
        for(int i = 0; i < (s.length>>>1); i++){
            int j = s.length-1-i;
            char c = s[i];
            s[i] = s[j];
            s[j] = c;
        }
    }
}

3、541. 反转字符串 II

分两步处理,先想想怎么获取需要反转的字符串,再想想反转字符串需要怎么做。

怎么获取需要反转的字符串:

        i代表需要反转的字符串的第一个位置,每次加2k。那么需要反转的位置就是从i到i+k,也就是[i, i+k),那么如果不足呢,如果长度不足加k,那么就反转从i到总长度的位置就行,要是不足2k不用处理,因为会默认处理i到i+k,剩下的部分不会进入循环。

再想想反转字符串需要怎么做:

跟刚才反转字符串的题一样,我先把它抽取成一个方法,需要反转的开始和结束位置。

i需要遍历到end+begin除以2,如图,这就是它的中间值。

双非本科准备秋招(10.1)—— 力扣刷题_第2张图片

然后j是end-(i-begin)-1,i-begin的取值会是0,1,···,所以j会不断缩小。

class Solution {
    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();
        for(int i = 0; i < chars.length; i+=2*k){
            if(i+k > chars.length){
                reverseString(chars, i, chars.length);
                break;
            }
            reverseString(chars, i, i+k);
        }
        return new String(chars);
    }
    public void reverseString(char[] s, int begin, int end) {
        for(int i = begin; i < ((end+begin)>>>1); i++){
            int j = end-(i-begin)-1;
            char c = s[i];
            s[i] = s[j];
            s[j] = c;
        }
    }
}

你可能感兴趣的:(leetcode,算法,求职招聘,java)