[LeetCode-Classic Interview 150 Questions-day8]

11. The container that holds the most water

Question meaning:

Given an  n integer array  of length height . There is  n a perpendicular line,  i the two endpoints of the line are  (i, 0) and  (i, height[i]) .

Find the two lines so that  x together with the axis they form a container that can hold the most water.

Returns the maximum amount of water the container can store.

Note: You cannot tilt the container.

【Input sample】

[1,8,6,2,5,4,8,3,7]

[Output sample] 49

Problem-solving idea: Convert to find the maximum area of ​​a rectangle

1. The double pointers i and j point to the head and tail of the array respectively. The distance between i and j is the length of the rectangle.

2. The height of the rectangle is min(height[i],height[j]),

3. Define a variable to store the largest area that can be found

Start drying

class Solution {
    public int maxArea(int[] height) {
        int i = 0,j = height.length - 1;
        int maxWater = 0;
        while(i<j){
            //i不能等于j,等于j只是一条垂线,没有面积,没有办法盛水
            maxWater = Math.max(maxWater,(j-i)* Math.min(height[i],height[j]));
            if(height[i] < height[j]){
                //当左边比右边小时,左指针i往右走,看在减少长度的时候,能不能增加高度
                ++i;
            }else{
                --j;
            }
        }
        return maxWater;
    }
}

Time: Beat 59.09%

Memory: Beaten by 16.11%

 15.Sum of three numbers

Question meaning:

Given an integer array  nums , determine whether there is a triple  [nums[i], nums[j], nums[k]] that satisfies  i != j, i != k and  j != k , and also satisfies  nums[i] + nums[j] + nums[k] == 0 . please

You return all  0 triples whose sum equals and does not repeat.

Note: Answers cannot contain duplicate triples.

【Input sample】

nums=[-1,0,1,2,-1,-4]

[Output sample][[-1,-1,2],[-1,0,1]]

Problem-solving ideas: sorting + double pointers

1. Sort the array first (in ascending order) (note that the values ​​of a, b, and c below are subscripts)

2. Enumerate a, and after determining a, determine b(a+1) and c(nums.length-1) from the remaining array, and determine the relationship between the addition of the three and 0. If they are equal, fill in This triplet is added to result; if it is less than 0, then b++, move to the right to find the larger one; if the sum of the three is greater than 0, reduce c. The internal loop termination condition for b and c is b>=c, rather than a+b+c=0, because there may be multiple values, such as nums[a] is -3, nums[b], nums[c ] can be -2 and 5, or -1 and 4;

3.a continues to enumerate until nums[a] itself is greater than 0, and the loop ends

4. The question requires that repeated triples cannot be included. When determining a, you need to determine whether the value of nums[a-1] is equal to nums[a]. If equal, it cannot be used again. Continue traversing, and the same goes for b and c.

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        int a,b,c;
        List<List<Integer>> result = new ArrayList<>();
        for(a=0;a<nums.length;a++){
            if(nums[a] > 0) break;
            if(a > 0 && nums[a] == nums[a-1]) continue;//继续寻找下一个a
            b = a+1;
            c = nums.length-1;
            while(b < c){
                int sum = nums[a]+nums[b]+nums[c];
                if( sum < 0){
                    ++b;
                }else if(sum > 0){
                    --c;
                }else{
                    List<Integer> r1 = Arrays.asList(nums[a], nums[b], nums[c]);
                    result.add(r1);
                    while(b < c && nums[b] == nums[b+1]) ++b;
                    while(b < c && nums[c] == nums[c-1]) --c;
                    ++b;
                    --c;
                }
                
            }
        }
        return result;
    }
}

Time: Beat 91.31%

Memory: Beaten by 64.32%

 209.Subarray with minimum length

Question meaning:

Given an  n array of positive integers and a positive integer  target .

Find the contiguous subarray in the array with the smallest length that  satisfies its sum  , and return its length . If there is no matching subarray, return   . ≥ target  [numsl, numsl+1, ..., numsr-1, numsr]0

【Input sample】

target = 7,nums=[2,3,1,2,4,3]

[Output sample] 2

Problem-solving ideas:

Violent enumeration, pay attention to the requirements in the question, it is greater than or equal to target, and it is a continuous subarray

Violent enumeration will time out, only for learning reference

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //注意求的是大于等于target,并且是一段连续的子数组
        int result = nums.length + 1;
        int sum = 0;//子序列的数值之和
        int subLength = 0;//子序列的长度
        for(int i=0;i<nums.length;++i){//子序列开始
            sum = 0;
            for(int j = i;j<nums.length;++j){//子序列结束
                sum += nums[j];
                if(sum >= target){
                    //更新结果
                    subLength = j-i+1;
                    result = result < subLength ? result : subLength;
                    break;//从下一个i继续找
                }
            }
        }
        return result == nums.length + 1 ? 0: result;
    }
}

Problem-solving ideas:

Using double pointers to implement sliding window solution

1. Pointer j points to the end position of the window

2. Pointer i points to the starting position of the window

3. Enumerate the positions of j and continuously accumulate them. When sum is greater than or equal to target, you can try to move i to the right to see if the result is still greater than target. Note that before i++, sum-=nums[i] is necessary. , because after taking a step to the right, the sum in the window does not include nums[i].

4. During the sliding process of the window, it is constantly judged whether the length of the current condition is smaller than the result.

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //滑动窗口
        //指针i指向窗口的左边,指针j指向窗口的右边
        //根据窗口的和值是否大于target来判断是否要移动窗口看
        int result = nums.length + 1;
        int sum = 0;//子序列的数值之和
        int subLength = 0;//子序列的长度
        int i =0;//默认每次窗口的其实位置都是第一位
        for(int j=0;j<nums.length;++j){//子序列开始
            sum += nums[j];
            while(sum >= target){
                //当加起来的值大于目标值之后,可以判断此时i能不能往前滑动
                subLength = j-i+1;
                result = result < subLength ? result : subLength;
                sum -= nums[i];
                ++i;//判断i往右滑动一步之后,是否还能符合条件,不能的话,内层while结束,外层j继续滑动
            }
        }
        return result == nums.length + 1 ? 0: result;
    }
}

Time: Beat 99.69%

Memory: Beaten by 57.73%

 3. The longest string without repeated characters

Question meaning:

Given a string  s , please find  the length of the longest substring  that does not contain repeated characters .

【Input sample】

s="abcabcbb"

[Output sample] 3

Problem-solving ideas:

Because the 150 classic interview questions were summarized in a sliding window, and the previous question 209 was the first sliding window question I did, so I immediately guessed that it would be implemented using a sliding window.

Do not repeat characters, consider using map and use characters as keys

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if(s.length()==0){
            return 0;
        }
        int i=0;
        int subLength = 0;
        int result = 0;
        Map<Character,Integer> map = new HashMap<>();
        for(int j=0;j<s.length();++j){
            char c = s.charAt(j);
            while(map.containsKey(c)){
                //如果map已经有这个字符了,左指针往右挪一步
                //挪动前需要先删掉
                map.remove(s.charAt(i));
                ++i;
            }
            map.put(c,j);
            result = Math.max(result,j-i+1);
        }
        return result;
    }
}

Time: Beat 20.12%

Memory: Beaten by 41.36%

Guess you like

Origin blog.csdn.net/qq_37998848/article/details/132360410