第01講:常用數據結構
1.1 字符串轉化
數組和字符串是最基本的數據結構,在很多編程語言中都有着十分相似的性質,而圍繞着它們的算法面試題也是最多的。
很多時候,在分析字符串相關面試題的過程中,我們往往要針對字符串當中的每一個字符進行分析和處理,甚至有時候我們得先把給定的字符串轉換成字符數組之後再進行分析和處理。
舉例:翻轉字符串“algorithm”。
解法:用兩個指針,一個指向字符串的第一個字符 a,一個指向它的最後一個字符 m,然後互相交換。交換之後,兩個指針向中央一步步地靠攏並相互交換字符,直到兩個指針相遇。這是一種比較快速和直觀的方法。
注意:由於無法直接修改字符串裏的字符,所以必須先把字符串變換爲數組,然後再運用這個算法。
public class Test {
public static void main(String[] args) {
String str = "algorithm";
char[] arr = str.toCharArray();
for (int i = 0; i < arr.length/2; i++) {
char tmp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = tmp;
}
String ret = String.valueOf(arr);
String ret1 = new String(arr);
System.out.println(ret);
System.out.println(ret1);
}
}
1.2 有效的字母異位詞
LeetCode 第 242 題:給定兩個字符串 s 和 t,編寫一個函數來判斷 t 是否是 s 的字母異位詞。
說明:你可以假設字符串只包含小寫字母。
示例 1
輸入: s = "anagram", t = "nagaram"
輸出: true
示例 2
輸入: s = "rat", t = "car"
輸出: false
public class TestDemo {
public static boolean isAnagram(String s,String t) {
if(s.length() != t.length()) {
return false;
}
int[] a = new int[26];
int[] b = new int[26];
for (int i = 0; i < 26; i++) {
a[i] = 0;
b[i] = 0;
}
for (int i = 0; i < s.length(); i++) {
a[s.charAt(i) - 'a'] ++;
b[s.charAt(i) - 'a'] ++;
}
for (int i = 0; i < 26; i++) {
if(a[i] != b[i]) {
return false;
}
}
return true;
}
public static void main(String[] args) {
String s = "anagram";
String t = "nagaram";
System.out.println(isAnagram(s, t));
}
}
public class TestDemo {
public static boolean isAnagram(String s,String t) {
if(s.length() != t.length()) {
return false;
}
int[] a = new int[26];
for (int i = 0; i < 26; i++) {
a[i] = 0;
}
for (int i = 0; i < s.length(); i++) {
a[s.charAt(i) - 'a'] ++;
}
for (int i = 0; i < t.length(); i++) {
a[t.charAt(i) - 'a'] --;
}
for (int i = 0; i < 26; i++) {
if(a[i] != 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
String s = "anagram";
String t = "nagaram";
System.out.println(isAnagram(s, t));
}
}
public static boolean isAnagram(String s,String t) {
if(s.length() != t.length()) {
return false;
}
char[] a = s.toCharArray();
char[] b = t.toCharArray();
Arrays.sort(a);
Arrays.sort(b);
for (int i = 0; i < b.length; i++) {
if(a[i] != b[i]) {
return false;
}
}
return true;
}
第08講:高頻真題解析 I
例題分析一
LeetCode 第 03 題:給定一個字符串,請你找出其中不含有重複字符的最長子串的長度。
示例 1
輸入:"abcabcbb"
輸出:3
解釋:因爲無重複字符的最長子串是"abc",其長度爲3。
示例 2
輸入:"bbbbb"
輸出:1
解釋:因爲無重複字符的最長子串是 "b",其長度爲 1。
示例 3
輸入:"pwwkew"
輸出:3
解釋:因爲無重複字符的最長子串是 "wke",其長度爲 3。
注意:答案必須是子串的長度,"pwke" 是一個子序列,不是子串。
public static int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<Character>();
int max = 0;
for (int j = 0; j < s.length(); j++) {
int i = 0;
while(set.contains(s.charAt(j))) {
set.remove(s.charAt(i));
i++;
}
set.add(s.charAt(j));
max = Math.max(max, set.size());
}
return max;
}
優化的線性法:
public static int lengthOfLongestSubstring(String s){
Map<Character,Integer> map = new HashMap<>();
int max = 0;
for(int i = 0, j = 0; j < s.length(); j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(i, map.get(s.charAt(j)) + 1);
}
map.put(s.charAt(j), j);
max = Math.max(max, j - i + 1);
}
return max;
}