21年10月第五周 力扣每日一题记录

本周每日一题 题目

  • lc240. 搜索二维矩阵 II
  • lc496. 下一个更大元素 I
  • lc301. 删除无效的括号
  • lc869. 重新排序得到 2 的幂
  • lc260. 只出现一次的数字 III

10-25 lc240. 搜索二维矩阵 II

  • 周日忙着刷科四的题和科三练车,所以题就没刷,27号补上。一天刷了1k道科四的题,最后科四也是满分了,基本所有题全都背下来了,我觉得还是有必要的,毕竟以后要上路的
  • 这题是简单题,有排序的矩阵二分查找,比较简单,没啥好说的
class Solution {
    
    
    public boolean searchMatrix(int[][] matrix, int target) {
    
    
        if(matrix==null||matrix.length==0||matrix[0].length==0) return false;
        int m = matrix.length, n = matrix[0].length;
        int i = m-1, j = 0;
        while(i<m&&i>=0&&j<n&&j>=0){
    
    
            if(matrix[i][j]<target) j++;
            else if(matrix[i][j]>target) i--;
            else return true;
        }
        return false;
    }
}

10-26 lc496. 下一个更大元素 I

  • 当天去考驾照了,所以27号补的,顺利拿到驾照哈哈哈
  • 本题就是对每个nums1中的元素,找到在nums2中下一个第一个大的元素即可,没有这个元素或者没有下一个第一个大的元素,就填-1
  • 因为要保证O(N1+N2)的时间复杂度,所以需要牺牲一定的空间
  • 那么思路很简单,先统计nums2的每个元素下一个第一个大的情况,放进map,然后再去遍历nums1,从map中获取,填入结果数组 即可
class Solution {
    
    
    //要求有时间复杂度限制,但是没有空间复杂度限制
    //应该所有nums1的元素都能够在nums2中找到对应,那么从一开始就直接统计nums2中的每个元素右边第一个大于自己的数就可以
    //然后放到map中,在遍历nums1时,查询就ok
    //这里的不重复指的是nums2中的元素不重复,nums1其实无所谓
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
    
    
        //统计nums2的情况
        Map<Integer,Integer> map = new HashMap<>();
        Deque<Integer> stack = new LinkedList<>();
        for(int i=nums2.length-1; i>=0; i--){
    
    
            while(!stack.isEmpty()&&stack.peek()<=nums2[i]) stack.pop();
            map.put(nums2[i],stack.isEmpty()?-1:stack.peek());
            stack.push(nums2[i]);
        }
        //遍历nums1的情况
        int[] res = new int[nums1.length];
        for(int i=0; i<nums1.length; i++) res[i] = map.getOrDefault(nums1[i],-1);

        return res;
    }
}

10-27 lc301. 删除无效的括号

  • 因为要所有可能的结果,所以要穷举所有的结果
  • 用bfs,每次删除一个括号,每个位置都有可能删除
  • 思路就是把每个位置都尝试删除,然后放进set里进行下一次遍历
  • 因为是bfs,所以当有一个已经符合的时候,此时已经达到最小路径了,即删除最小数量的括号,那么这一轮循环必须结束
class Solution {
    
    
    //用bfs的思路, 每次删除一个括号, 这里不删除非括号字符哦
    //用set来维护当前结果, 使得不重复
    //如果一旦出现有符合的, 则当前轮次结束, 将结果输出
    public List<String> removeInvalidParentheses(String s) {
    
    
        Set<String> set = new HashSet<>();
        set.add(s);
        List<String> res = new ArrayList<>();
        boolean flag = false;
        while(!set.isEmpty()&&!flag){
    
    
            Set<String> curSet = new HashSet<>();
            for(String str:set){
    
    
                if(check(str)){
    
    
                    res.add(str);
                    flag = true;//循环终止条件
                }
                if(flag) continue;//当前已经是最短,没有必要再进行下去了,把set中校验完就好
                int n = str.length();
                for(int i=0; i<n; i++){
    
    
                    char ch = str.charAt(i);
                    if(ch!='('&&ch!=')') continue;
                    curSet.add(str.substring(0,i)+str.substring(i+1,n));//这里的常数时间有点大其实
                } 
            }
            set = curSet;
        }
        return res;
    }
	//通过做括号大于等于右括号,来判断是否符合情况
    private static boolean check(String s){
    
    
        char[] ss = s.toCharArray();
        int l=0, r=0;
        for(char ch: ss){
    
    
            if(ch=='(') l++;
            else if(ch==')') r++;
            if(l<r) return false;
        }
        return l==r;
    }
}

10-28 lc869. 重新排序得到 2 的幂

  • 本题最简单,最取巧,最聪明的做法是列举出所有的2进制数,然后将其拆散放进set中,然后对输入的数进行对比。
  • 这种时间复杂度最低,因为2的幂本来就没几个,然后进行对比的时候,挨个字符到set中找,只要找不到,或者长度对应不对,就直接返回false
  • 这种方式很简单,这里就不写了
  • 方法二:将当前传入数字转成字符数组,进行全排列,然后挨个进行判定
  • 小tips:(n&(n-1))==0;//判断是不是为2的幂的小技巧
  • 代码为方法二,主要是练下手,很久没写全排列了
class Solution {
    
    
    private static boolean res;
    //就是将数字重排序,如果是1e9,那么最多9位数,可能性就是9!种可能,全部枚举然后,分别计算
    //注意开头不能是0, 然后得剪枝
    public static boolean reorderedPowerOf2(int n) {
    
    
        res = false;
        //全排列 swap一下
        char[] ss = String.valueOf(n).toCharArray();
        rank(ss,0);
        return res;
    }

    private static void rank(char[] ss, int index){
    
    
        if(res||ss[0]=='0') return;//强制结束
        if(index>=ss.length){
    
    
            res = help(ss);
            return;
        }
        Set<Character> set = new HashSet<>();
        for(int i=index; i<ss.length; i++){
    
    
            if(set.contains(ss[i])) continue;//去除掉重复的,剪枝
            swap(ss,index, i);
            rank(ss, index+1);
            swap(ss,index, i);
            set.add(ss[i]);
        }
    }

    private static void swap(char[] ss, int i, int j){
    
    
        char t = ss[i];
        ss[i] = ss[j];
        ss[j] = t;
    }

    //判断是不是2的幂
    private static boolean help(char[] ss){
    
    
        int n = Integer.valueOf(new String(ss));
        // while(n%2==0&&n!=0) n /= 2;
        // return n==1||n==0;
        return (n&(n-1))==0;//判断是不是为2的幂的小技巧
    }
}
  • 然后我又在评论区看到一个很厉害的评论,直接利用排序,就解决了比较是否2幂的问题,贴出来记录一下
//引自leetcode用户liet.start在本题的评论 如有侵权,请告知
public boolean reorderedPowerOf2(int N) {
    
    
        String[] rec ={
    
    "1","2","4","8","16","23","46","128","256","125","0124","0248","0469","1289","13468",
                        "23678","35566","011237","122446","224588","0145678","0122579","0134449","0368888",
                        "11266777","23334455","01466788","112234778","234455668","012356789","0112344778"};
        char[] at = String.valueOf(N).toCharArray();
        Arrays.sort(at);
        String str = new String(at);
        for(String p:rec){
    
    
            if(str.equals(p)) return true;
        }
        return false;
    }

10-30 lc260. 只出现一次的数字 III

  • 这题也是剑指上的题
  • 这种题都是要异或,然后异或的结果是两个目标值的异或值。
  • 很明显,两个目标值不同,差异就在于二进制上,那么任选一个二进制来将两个目标值分到不同的部分,其他数也可以用这个二进制位来进行划分,从而问题变成了两个:从一个整数数组中,其中恰好只有一个元素出现一次,其他的都出现了两次, 选出目标值
class Solution {
    
    
    public int[] singleNumber(int[] nums) {
    
    
        int sum = 0;
        for(int num: nums) sum ^= num;
        //寻找sum的从右往左第一位不为0的
        int index = 0;
        while(((1<<index)&sum)==0) index++;
        //寻找第一个目标值
        int t = 0;
        for(int num: nums) if(((1<<index)&num)==0) t ^= num;
        return new int[]{
    
    t,sum^t};
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34687559/article/details/120985791
今日推荐