// 这种单纯的遍历的时间复杂度太高了, 遂放弃 publicintmaxRectangle(int p, int q, int m, int n, char[][] matrix){ for(int i = p ; i <= m ; i ++ ){ for(int j = q ; j <= n ; j ++ ){ if(matrix[i][j] == 0){ return0; } } }
classSolution{ public List<Integer> findAnagrams(String s, String p){ // 想到了哈希表 // 计算字符串 p 的长度 n ,将 p 中每个字符存入 key, value 为 字符出现的个数 // 从左往右遍历字符串 s, 并且循环遍历 n 次 int m = s.length(); int n = p.length();
List<Integer> res = new ArrayList<Integer>(); HashMap<Character, Integer> map = new HashMap<Character, Integer>(); // 得到遍历字符串 p 后的哈希表 for(int j = 0 ; j < n ; j ++ ){ Character ch = p.charAt(j); Integer count = map.get(ch); count = count == null ? 1 : ++ count; map.put(ch, count); }
for(int i = 0; i < m ; i ++ ){ // 复制一个哈希表 HashMap<Character, Integer> itemMap = (HashMap<Character, Integer>) map.clone(); int j = i; // 从 i 开始,连续遍历 n 个 字符,如果字符在哈希表中,则将对应的 value 减 1; // 如果不在哈希表,则直接结束循环 for(j = i; j < i + n && j < m; j ++ ){ Character ch = s.charAt(j); Integer count = itemMap.get(ch); if(count == null || count == 0){ break; }else{ count --; itemMap.put(ch, count); } } // 如果是正确匹配了全部子串,则把子串的头索引加入列表中 if(j == i + n){ res.add(new Integer(i)); } }
classSolution{ publicintsubarraySum(int[] nums, int k){ // 第一想法是递归 // 再看看发现有子数组是连续的 // 思路:滑动窗口,设置左右指针 // 问题出在 元素可以为负值,不可以使用滑动窗口 int count = 0; int sum = 0;
// 想要用队列,FIFO,先进先出 LinkedList<Integer> queue = new LinkedList<Integer>();
int left = 0; int right = 0; while(right < nums.length){ if(nums[right] + sum < k){ queue.add(nums[right]); sum += nums[right]; } if(nums[right] + sum == k){ queue.add(nums[right]); sum += nums[right]; count ++; } while(nums[right] + sum > k && left < right){ sum -= queue.removeFirst(); left ++; } right ++; }
return count; } }
测试结果
枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution{ publicintsubarraySum(int[] nums, int k){
// 简单枚举 int count = 0; for(int i = 0 ; i < nums.length; i ++ ){ int sum = 0; for(int j = i ; j >= 0 ; j -- ){ sum += nums[j]; if(sum == k){ count ++; } } }