zoukankan      html  css  js  c++  java
  • LeetCode第152场周赛(Java)

    这算是我第一次正式参加 LeetCode 的周赛吧。通过两道题。意料之中(通过上次模拟可以看出来)。总的来说,脑袋还是不太灵光。想的有点慢。全球第一名 0:10:19 就全部通过。。。感觉我的智商被狠狠的摁在地上摩擦了。

    参考:huntersjm


    5175. 构建回文串检测

    我第一次提交的直接 TLE。然后就没有然后了。

    TLE 代码的思路(可以不看):

    • 定义一个 int 型的 notParesNum 保存字母个数为奇数的字母的数量。
    • 每次检测,将 [left, right] 字串取出,统计里面每种字母的个数,如果个数是奇数,那么将 notParesNum 数量加 1。
    • 统计结束后,检查 notParesNum / 2k的关系。如果是大于,那么就是 false,否则就是 true

    改进一次后的思路:

    • 在循环过程中就检查 notParesNum / 2k的关系。如果是 false,直接 continue

    依然超时了。然后就没时间了,我就没想了。

    正确思路:

    • 先要进行预处理。定义 int 型二维数组 charNum[length + 1][26]。其中 length 为字符串 s 的长度。并且 charNum[0] 不保存数据。
    • 每次检测的时候,先检查 k 的值,如果大于等于 25,那么一定可以将子串替换成回文串,因为最多 26 种字母。(不超时的关键点
    • 再检测子串的长度的一半是否超过 k,如果不超过,那么一定可以将子串替换成回文串。(次关键点
    • 过滤上面两部分后,就来最后一种情况,计算 charNum[right]charNum[left] 的差值,统计字母个数为奇数的字母个数 notParesNum
      • 统计差值的时候要注意 26 个字母中,有一个字母的个数要额外加 1。具体见代码。
    • 统计结束后,检查 notParesNum / 2k 的关系。如果是大于,那么就是 false,否则就是 true

    运算符优先级从高到低顺序:+ -<< >>< > <= >=||=

    代码如下:

    class Solution {
    	public List<Boolean> canMakePaliQueries(String s,
    											int[][] queries) {
    		// 1、预处理,统计每种字母的个数
    		int length = s.length();// 字母个数
    		int[][] charNum = new int[length + 1][26];// 保存个数
    		char[] arrS = s.toCharArray();
    		for (int i = 0; i < length; ++i) {
    			int ch = arrS[i] - 'a';
    			charNum[i + 1] = Arrays.copyOf(charNum[i], 26);// 其它字母个数相同
    			++charNum[i + 1][ch];// 字母arrS[i]个数加 1
    		}
    
    		// 2、保存结果
    		List<Boolean> ans = new ArrayList<>();
    
    		// 3、检测每个子串是否可以变成回文串
    		for (int[] querie : queries) {
    			int left = querie[0];
    			int right = querie[1];
    			int k = querie[2];
    
    			// 26个字母,最多25次就能替换成回文串,或者子串长度的一半不超过k
    			if (k >= 25 || (right - left + 1) >> 1 <= k) {
    				ans.add(true);// 一定能用不超过k次替换就能变成回文串
    				continue;
    			}
    
    			// 超过k次的话,就检查非成对字母的个数的一半是否超过k
    			int notParesNum = 0;// 非成对字母个数
    			int ch = arrS[left] - 'a';// 左边界字母
    
    			// 统计子串中每个字母的个数,如果个数为奇数,notParesNum加1
    			for (int i = 0; i < 26; ++i) {
    				// 由于是从charNum[1]开始保存数据,故下标要加1
    				int num = charNum[right + 1][i] - charNum[left + 1][i];
    
    				if (i == ch) {// i是左边界字母
    					++num;// 个数加1,因为上一步计算差值的时候没有加上这一个
    				}
    
    				if (0 != (num & 1)) {// 当前字母个数为奇数
    					++notParesNum;// 非对称字母个数加1
    				}
    			}
    
    			// 非对称的字母可以通过改变变成同一字母,故除以2
    			if (notParesNum >> 1 > k) {// 替换次数超过k次
    				ans.add(false);
    			} else {// 替换次数不超过k次
    				ans.add(true);
    			}
    		}
    
    		return ans;// 返回结果
    	}
    }
    

    提交结果:
    5175


    5176. 猜字谜

    什么题目,一直超时超时。参考了别人的代码,用它的代码提交了 7、8 次,只有一次通过了。。就一句话解释算了。

    int 型数保存字符串的字母情况,低 26 位,每一位保存对应位的字母是否存在,1 表示存在,0 表示不存在。

    运算符优先级从高到低顺序:+ -<< >>==&||=

    代码如下:

    class Solution {
        public List<Integer> findNumOfValidWords(	String[] words,
                                                    String[] puzzles) {
            int[] codeWords = new int[words.length];// 保存编码后的值
            for (int i = 0; i < words.length; ++i) {
                codeWords[i] = code(words[i]);// 给每个单词编码
            }
    
            List<Integer> ans = new ArrayList<>();
            for (String puzzle : puzzles) {// 遍历所有谜面
                int codePuzzle = code(puzzle);// 给谜面编码
                int count = 0;// 谜底个数
                for (int value : codeWords) {// 遍历所有单词的编码
                    if ((codePuzzle & value) == value) {// 单词中字母全都在谜面中
                        if ((value >> puzzle.charAt(0) - 'a' & 1) == 1) {
                            ++count;// 单词包含谜面首字母,谜底个数加1
                        }
                    }
                }
                ans.add(count);// 个数添加到结果中
            }
            return ans;// 返回结果
        }
    
        // 整数的低26位保存字符串的字母信息,包含字母,对应位置1
        private int code(String str) {// 将字符串编码成整数
            int num = 0;
            int length = str.length();
            for (int i = 0; i < length; ++i) {
                num |= 1 << str.charAt(i) - 'a';
            }
            return num;// 返回编码后的值,低26位,每一位代表一个字母
        }
    }
    

    提交结果:
    5176

  • 相关阅读:
    Application package 'AndroidManifest.xml' must have a minimum of 2 segments.
    让“是男人就下到100层”在Android平台上跑起来
    移植一个cocos2d-x游戏
    cocos2d-x宏定义
    职场之需求
    cocos2d-x for android配置 & 运行 Sample on Linux OS
    input函数出现的问题(Python)
    职场之英语
    职场之随手记
    应用商店后台MIS的一些思考
  • 原文地址:https://www.cnblogs.com/wowpH/p/11687401.html
Copyright © 2011-2022 走看看