LC 2 pointer summary

最近按照tag来刷,2 pointer

基本思想:根据2 pointer计算出一个value,根据这个value决策该怎么移动哪个pointer

相关的题目有:在一个数组中找N个数加起来等于M,数组存水,链表环相交,merge sort,sliding window问题,sliding window在子数字一系列问题中的应用。。。。(想到在总结)


贴几个值得一看的题目

3. Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring"pwke" is a subsequence and not a substring.

package l3;

import java.util.HashSet;
import java.util.Set;

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        char[] cs  =s.toCharArray();
        int p=0, q=0, max=0;
        Set<Character> set = new HashSet<Character>();
        
        while(q<s.length()) {
        	max = Math.max(max, q-p);
        	
        	if(!set.contains(cs[q]))	set.add(cs[q++]);
        	else {
        		while(cs[p] != cs[q]) {
        			set.remove(cs[p]);
        			p++;
        		}
        		p ++;   
        		q ++;
        	}
        }
        max = Math.max(max, q-p);
        
        return max;
    }
}


30. Substring with Concatenation of All Words

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s"barfoothefoobarman"
words["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

package l30;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
 * sliding window(利用words中的字符串等长这一条件)
 * 把题目降维:把String考虑成Character的话很容易想到sliding window
 * 再jump回原问题,只要遍历前m个位置开始就OK了(m为words中string的长度)
 */
public class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
    	List<Integer> ret = new ArrayList<Integer>();
    	int m = words[0].length();
    	
    	Map<String, Integer> map0 = new HashMap<String, Integer>();
		for(String w : words)	
			if(map0.containsKey(w))	map0.put(w, 1+map0.get(w));
			else	map0.put(w, 1);
		
    	for(int i=0; i<m; i++) {
    		Map<String, Integer> map = new HashMap<String, Integer>(map0);
    		int p = i, q = i;
    		
    		// 外扩(区别于匹配不上和Map为空2中情况)
			while(q+m<=s.length()) {
				String t = s.substring(q, q+m);
    			if(map.containsKey(t)) {
    				int cnt = map.get(t);
    				if(cnt == 1)	map.remove(t);
    				else map.put(t, cnt-1);
    				if(map.isEmpty()) {
    					ret.add(p);
    					map.put(s.substring(p, p+m), 1);
    					p+=m;
    				}
    				q+=m;
    			} else {
    				while(true) {
    					String st = s.substring(p,p+m);
    					if(st.equals(t)) break;
    					map.put(st, map.containsKey(st)?map.get(st)+1:1);
    					p+=m;
    				}
    				q+=m;
    				p+=m;
    			}
			}
    	}
    	
    	return ret;
    }
}


76. Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S = "ADOBECODEBANC"
T = "ABC"

Minimum window is "BANC".

Note:
If there is no such window in S that covers all characters in T, return the empty string "".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

package l76;

import java.util.HashMap;
import java.util.Map;

/*
 * sliding window
 * 解决大多数的字符串子串问题
 */
public class Solution {
    public String minWindow(String s, String t) {
        char[] ss = s.toCharArray();
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        for(char c : t.toCharArray()) {
        	if(!map.containsKey(c))	map.put(c, 1);
        	else map.put(c, map.get(c)+1);
        }
        
        int min = Integer.MAX_VALUE, start = 0;
        int need = t.length();
        int p=0, q=0;
        while(true) {
        	while(q<ss.length && need > 0) {
        		if(map.containsKey(ss[q])) {
        			if(map.get(ss[q])>0) {
            			map.put(ss[q], map.get(ss[q])-1);
            			need--;
        			} else {
        				map.put(ss[q], map.get(ss[q])-1);
        			}
        		}
        		q++;
        	}
        	
        	while(need == 0) {
        		if(map.containsKey(ss[p])) {
        			map.put(ss[p], map.get(ss[p])+1);
        			if(map.get(ss[p]) > 0) {
        				if(q-p < min) {
        					min = q-p;
        					start = p;
        				}
        				need ++;
        				p++;
        				break;
        			}
        		}
        		p++;
        	}
        	
        	if(q == ss.length)	break;
        }
        
        return min==Integer.MAX_VALUE ? "" : s.substring(start, start+min);
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值