【LeetCode】笔记1

1. Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have
exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[**0**] + nums[**1**] = 2 + 7 = 9,
return [**0**, **1**].

Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
public int[] twoSum(int[] numbers, int target) {
int[] result = new int[2];
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < numbers.length; i++) {
if (map.containsKey(target - numbers[i])) {
result[1] = i;
result[0] = map.get(target - numbers[i]);
return result;
}
map.put(numbers[i], i);
}
return result;
}

使用Hashmap结构,将值存在key,数组索引序号存在value里,使用containsKey方法简易地寻找和为target的对应项,若存在则返回对应下标,不存在就加入到map中。


3. Longest Substring Without Repeating Characters

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

Example 1:

Input: “abcabcbb”
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:

Input: “bbbbb”
Output: 1 Explanation: The answer is "b", with the length of 1.

Example 3:

Input: “pwwkew”
Output: 3 Explanation: 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.
即寻找最长连续子串

Solution

public int lengthOfLongestSubstring(String s) {
    int n=s.length();
    HashSet<Character> sett=new HashSet<>();
    int maxlen=0,j=0,k=0;
    while (j<n&&k<n) {
        if(sett.contains(s.charAt(j))) {
            sett.remove(s.charAt(k));
            k++;
        }else {
            sett.add(s.charAt(j));
            j++;
            maxlen=Math.max(maxlen, j-k);
        }
    }
    return maxlen;
}

利用HashSet结构,从字符串开始处索引,当没有重复字符时,定义的一个指针j递增,并计算最长的子串长度,当遇到重复字符时,另一指针k递增,并逐个移除Set集合里的值,直到将重复的字符移出。


4. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

You may assume nums1 and nums2 cannot be both empty.

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5

Solution

A

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
    int m=nums1.length,n=nums2.length;
    int slen=m+n;
    int num[]=new int[slen];
    int j=0,k=0,i=0;
    while(j<m&&k<n){
        num[i]=(nums1[j]>nums2[k]?nums2[k++]:nums1[j++]);
        i++;
    }
    while(j<m){
        num[i++]=nums1[j++];
    }
    while(k<n){
        num[i++]=nums2[k++];
    }
    if(slen%2==1){
        return num[slen/2];
    }else{
        return (double)(num[slen/2]+num[slen/2-1])/2;
    }
}

这个算法很容易理解,就是把两个数组重新排序到一个大数组里,再算中位数就很容易。

B

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int len = m + n;
if(len % 2 == 0){
double left = (double)findKthHelper(nums1, 0, nums2, 0, len/2);
double right = (double)findKthHelper(nums1, 0, nums2, 0, len/2 + 1);
return (double)(left + right)/2;
}else{
return findKthHelper(nums1, 0, nums2, 0, len/2 + 1);
}
}
private int findKthHelper(int[] A, int aStart, int[] B, int bStart, int k){
if(aStart >= A.length){
return B[bStart + k - 1];
}
if(bStart >= B.length){
return A[aStart + k - 1];
}
if(k == 1){
return Math.min(A[aStart], B[bStart]);
}
int aMid = aStart + k/2 - 1;
int bMid = bStart + k/2 - 1;
int aVal = aMid >= A.length ? Integer.MAX_VALUE : A[aMid];
int bVal = bMid >= B.length ? Integer.MAX_VALUE : B[bMid];
if(aVal <= bVal){
return findKthHelper(A, aMid + 1, B, bStart, k - k/2);
}else{
return findKthHelper(A, aStart, B, bMid + 1, k - k/2);
}
}

基于二分法,比较AMid和BMid保留应该保留的部分递归,直至K==1.


5. Longest Palindromic Substring

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.

Example 2:

Input: “cbbd”
Output: “bb”

Solution

public String longestPalindrome(String s) {
    if(s.length()<1) return s;
    StringBuilder str=new StringBuilder(s);
    StringBuilder rs=new StringBuilder(s);
    rs.reverse();
    int len=s.length();
    String outstr="";
    for(int i=0;i<=len-1;i++) {
        for(int n=2;n<=len-i;n++) {
            if(str.substring(i, n+i).equals(rs.substring(len-n-i, len-i))) {
                if(str.substring(i, n+i).length()>outstr.length()) {
                    outstr=str.substring(i, n+i);
                } 
            }
        }
    }
    if(outstr.equals("")) {
        outstr=str.substring(0, 1);
    }
    return outstr;
}

将原字符串反转,通过比较对应位置的子字符串

Better Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private int lo, maxLen;

public String longestPalindrome(String s) {
int len = s.length();
if (len < 2)
return s;

for (int i = 0; i < len-1; i++) {
extendPalindrome(s, i, i); //assume odd length, try to extend Palindrome as possible
extendPalindrome(s, i, i+1); //assume even length.
}
return s.substring(lo, lo + maxLen);
}

private void extendPalindrome(String s, int j, int k) {
while (j >= 0 && k < s.length() && s.charAt(j) == s.charAt(k)) {
j--;
k++;
}
if (maxLen < k - j - 1) {
lo = j + 1;
maxLen = k - j - 1;
}
}

extendPalindrome方法选定一个中心,以两个指针j和k分别向俩个方向延伸,遍历完字符串即可。


10. Regular Expression Matching

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.

‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

Example 1:

Input:
s = “aa”
p = “a”
Output: false
Explanation: “a” does not match the entire string “aa”.

Example 2:

Input:
s = “aa”
p = “a
Output: true
Explanation:
‘ means zero or more of the precedeng element, ‘a’. Therefore, by repeating ‘a’ once, it becomes “aa”.

Example 3:

Input:
s = “ab”
p = “.
Output: true
Explanation: “.
“ means “zero or more (*) of any character (.)”.

Example 4:

Input:
s = “aab”
p = “cab”
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches “aab”.

Example 5:

Input:
s = “mississippi”
p = “misisp*.”
Output: false

Solution

正则表达式

public boolean isMatch(String s, String p) {
    java.util.regex.Pattern pattern=java.util.regex.Pattern.compile(p);
    java.util.regex.Matcher matcher=pattern.matcher(s);
    if(matcher.matches()) {
        return true;
    }else {
        return false;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public boolean isMatch(String s, String p) {
if (s == null || p == null) {
return s == p;
}
char[] sArray = s.toCharArray();
char[] pArray = p.toCharArray();
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
dp[0][0] = true;
for (int j = 1; j < dp[0].length; j++) {
if (p.charAt(j - 1) == '*') { // * is promised not to be the first char
dp[0][j] = dp[0][j - 2];
}
}
for (int i = 1; i < dp.length; i++) {
for (int j = 1; j < dp[0].length; j++) {
if (pArray[j - 1] == sArray[i - 1] || pArray[j - 1] == '.') {
dp[i][j] = dp[i - 1][j - 1];
} else if (pArray[j - 1] == '*') {
if (sArray[i - 1] == pArray[j - 2] || pArray[j - 2] == '.') {
dp[i][j] = (dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j]);
} else {
dp[i][j] = dp[i][j - 2];
}
}
}
}
return dp[dp.length - 1][dp[0].length - 1];
}