文章目录
53.最大子数组和【简单】
https://leetcode-cn.com/problems/maximum-subarray/
这道题可以用分治法,就是我们从数组第一个值开始遍历,维护一个sum。
当 sum <= 0 时,让 left = i;
当 sum > 0时, sum += nums[i]。
然后每次循环让 sum 与 res 的数值进行比较,如果 sum > res , res = sum。
对我来说,这道题比较难想的地方是如何去循环。并且本题只用输出最大值,而不是最大的子数组。要注意审题。
3.无重复字符的最长子串【中等】
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
这道题使用【滑动窗口】,利用【HashSet】或者【HashMap】判断是否产生重复。
算法描述:
遍历字符串,如果要加入的下一个字符在之前已经加入 set/map ,令left指针移动到曾经加进来的那个重复字符的后一个(如:abcdec,left 移动到指向 d 的位置)。然后让 right++,把字符加入表中,计算长度,与max存的最大长度比较,维护max为最大长度。
这道题用 HashSet 和 HashMap 的区别是:
hashset 在移动 left 时要一个一个 set.remove(),hashmap 则是直接让 left 指向曾经加进去现在重复的下一个字符。
// HashMap
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character, Integer> map = new HashMap<>();
int left = 0, max = 0;
for (int i = 0; i < s.length(); i++) {
if (map.containsKey(s.charAt(i)))
left = Math.max(map.get(s.charAt(i))+1, left);
map.put(s.charAt(i),i);
max = Math.max(max, i - left + 1);
}
return max;
}
}
// HashSet
class Solution {
public int lengthOfLongestSubstring(String s) {
int max = 0, left = 0, right = 0;
char[] charArray = s.toCharArray();
Set<Character> set = new HashSet<>();
for (int i = 0; i < s.length(); i++) {
while(set.contains(charArray[i])){
set.remove(charArray[left]);
left ++;
}
set.add(charArray[i]);
max = Math.max(right - left + 1, max);
right ++;
}
return max;
}
}
5. 最长回文子串【中等】
https://leetcode-cn.com/problems/longest-palindromic-substring/
中心扩散法
算法描述: 从每一个位置出发,向两边扩散即可。遇到不是回文的时候结束。遍历每个字符,对于当前字符来说:首先往左寻找与当期位置相同的字符,直到遇到不相等为止。
然后往右寻找与当期位置相同的字符,直到遇到不相等为止。
最后左右双向扩散,直到左和右不相等。
class Solution {
public String longestPalindrome(String s) {
if (s == null || s.length() == 0) {
return "";
}
int left = 0, right = 0;
int maxLen = 0, maxStart = 0;
int len = 0;
for (int i = 0; i < s.length(); i++) {
left = i - 1;
right = i + 1;
len = 1;
while (left >= 0 && s.charAt(i) == s.charAt(left)) {
left --;
len ++;
}
while (right < s.length() && s.charAt(i) == s.charAt(right)) {
right ++;
len ++;
}
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left --;
right ++;
len = len + 2;
}
if(len > maxLen) {
maxLen = len;
maxStart = left;
}
len = 0;
}
return s.substring(maxStart + 1, maxStart + 1 + maxLen);
}
}
1143. 最长公共子序列【中等】
https://leetcode-cn.com/problems/longest-common-subsequence/
这道题采用动态规划。
dp数组与下标的含义: 以 text1 [ i - 1] 和 text2 [ i - 1 ] 为结尾的最长子序列长度。
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int n = text1.length(), m = text2.length();
int[][] dp = new int[n+1][m+1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (text1.charAt(i-1) == text2.charAt(j-1))
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]);
}
}
return dp[n][m];
}
}
逻辑智力题
一副扑克牌均分成三堆,大小王在同一堆的概率是多少?
答案为: 17/53