双指针题目

 比较含退格的字符串

 

给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。

class Solution {
    public boolean backspaceCompare(String S, String T) {
        int S_Len = S.length(), T_Len = T.length();
        char[] S_arr = S.toCharArray(), T_arr = T.toCharArray();
        int skipS = 0, skipT = 0;
        for (int i = S_Len - 1, j = T_Len - 1; i >= 0 || j >= 0; i--, j--) {
            while (i >= 0) {
                if (S_arr[i] == '#') {
                    skipS++;
                    i--;
                } else if (skipS > 0) {
                    // 遇到字符, 但由于需要回退, 所以还需要前移1位
                    skipS--;
                    i--;
                } else {
                    // 遇到字符, 且不能回退了, 所以需要比对这个字符是否与T对应位置上的字符相等
                    break;
                }
            }
            while (j >= 0) {
                if (T_arr[j] == '#') {
                    skipT++;
                    j--;
                } else if (skipT > 0) {
                    skipT--;
                    j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S_arr[i] != T_arr[j]) return false;
            } else if (i >= 0 || j >= 0) {
                // 有其中一方已经遍历完整个字符串, 但另外一方没有遍历完整个字符串, 直接返回false
                return false;
            }
        }
        return true;
    }
}

 有序数组的平方

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

class Solution {
    public int[] sortedSquares(int[] nums) {
        int right = nums.length - 1;
        int left = 0;
        int[] result = new int[nums.length];
        int index = result.length - 1;
        while (left <= right) {
            if (nums[left] * nums[left] > nums[right] * nums[right]) {
                result[index--] = nums[left] * nums[left];
                ++left;
            } else {
                result[index--] = nums[right] * nums[right];
                --right;
            }
        }
        return result;
    }
}

 76. 最小覆盖子串

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。 

输入:s = "ADOBECODEBANC", t = "ABC"
输出:"BANC"
class Solution {
    public String minWindow(String s, String t) {
        if (t.length() > s.length()) {
			return "";
		}
        Map<Character, Integer> need = new HashMap<>();// 统计所需字符及其数量
		for (int i = 0; i < t.length(); i++) {
			need.put(t.charAt(i), need.getOrDefault(t.charAt(i), 0) + 1);
		}
        Map<Character, Integer> window = new HashMap<>();// 统计窗口内的字符及其数量
		int valid = 0;// 满足条件的字符数
		int l = 0, r = 0;
		int min_LEN = Integer.MAX_VALUE, min_LEFT = 0;//记录最小窗口的长度和开始位置
		while (r < s.length()) {
			// 扩大右边界
			char ch = s.charAt(r);
			r++;
			window.put(ch, window.getOrDefault(ch, 0) + 1);
			if (window.get(ch).equals(need.get(ch))) {
				valid++;
			}

			// 满足条件时缩小窗口
			while (valid == need.size()) {
				// 记录当前窗口
				if (r - l < min_LEN) {
					min_LEN = r - l;
					min_LEFT = l;
				}

				// 缩小左边界
				char c = s.charAt(l);
				if (window.get(c).equals(need.get(c))) {
					valid--;
				}
				window.put(c, window.get(c) - 1);
				l++;
			}
		}
		return min_LEN == Integer.MAX_VALUE ? "" : s.substring(min_LEFT, min_LEFT + min_LEN);
    }
}

438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int sLen = s.length();
        int pLen = p.length();
        List<Integer> res = new ArrayList<>();
        int[] sBuc = new int[26]; //待处理词频桶
        int[] pBuc = new int[26]; //目标词频桶
        for(int i = 0; i < pLen; i++){ //统计目标词频
            pBuc[p.charAt(i) - 'a']++;
        }
        int l = 0; //左窗口
        for(int r = 0; r < sLen; r++){ //右窗口
            sBuc[s.charAt(r) - 'a']++; //记录待处理词频桶
            if(r - l + 1 > pLen){ //当窗口长度超过目标字符串长度
                sBuc[s.charAt(l++) - 'a']--; //左窗口向右移动, 同时清空刚才左窗口加入到待处理词频桶的字符
            }
            if(Arrays.equals(sBuc, pBuc)){ //如果待处理词频桶和左窗口词频桶内容一样
                res.add(l); //记录左窗口
            }
        }
        return res;
    }
}

字母异位词分组

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<String,Integer> hm=new HashMap();
        List<List<String>> list=new ArrayList();
        for(int i=0;i<strs.length;i++){
            String tmp=strs[i];
            Arrays.sort(tmp);
            if(hm.containsKey(tmp)){
                int index=hm.get(tmp);
                list.get(index).add(strs[i]);
            }else{
                List<String> list1=new ArrayList();
                list1.add(strs[i]);
                list.add(list1);
            }
        }
        return list;
    }
}

454. 四数相加 II

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        Map<Integer, Integer> map = new HashMap<>();
        int temp;
        int res = 0;
        //统计两个数组中的元素之和,同时统计出现的次数,放入map
        for (int i : nums1) {
            for (int j : nums2) {
                temp = i + j;
                if (map.containsKey(temp)) {
                    map.put(temp, map.get(temp) + 1);
                } else {
                    map.put(temp, 1);
                }
            }
        }
        //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
        for (int i : nums3) {
            for (int j : nums4) {
                temp = i + j;
                if (map.containsKey(0 - temp)) {
                    res += map.get(0 - temp);
                }
            }
        }
        return res;
    }
}

18. 四数之和

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> list = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            // 去重
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            for (int j =  i + 1; j < nums.length; j++) {
                if (j > i + 1 && nums[j] == nums[j - 1]) {
                    continue;
                }
                int left = j + 1;
                int right = nums.length - 1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum > target) {
                        right--;
…                        }
                        left++;
                        right--;
                    }
                }
            }
        }
        return list;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值