输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”
Time Limit Exceeded
)T.len
的S的子串:遍历T中的字符看其在子串中是否存在,若存在需要删除子串中的该字符,避免出现情况1;在最后更新result时,需要将result.len与原始的子串长度作比较,而不是直接sub.length(),避免出现情况2.情况1:
Input: “bbaa"和"aba”
Output: “bba”
Expected: “baa”
情况2:
Input: “abc"和"ab”
Output: “abc”
Expected: “ab”
Time Limit Exceeded
:public String minWindow(String s, String t) {
int tlen = t.length();
int slen = s.length();
String minString = "";
for (int i = 0; i < slen; i++) {
for (int j = i + tlen - 1; j < slen; j++) {
String sub = s.substring(i, j + 1);
boolean flag = true;
for (int k = 0; k < tlen; k++) {
int index = sub.indexOf(t.charAt(k));
if (index == -1) {
flag = false;
break;
} else {
sub = sub.substring(0, index) + sub.substring(index + 1);
}
}
if (flag) {
if (minString.equals("")) {
minString = s.substring(i, j + 1);
} else if (minString.length() > j - i + 1) {// 不能与当前的sub.len作比较,应该与初始时的sub.len作比较
minString = s.substring(i, j + 1);
}
}
}
}
return minString;
}
去除窗口前端多余字母
),若得到的窗口依然可行,则更新最小窗口大小。Hashmap
记录T中字母的个数,然后使用count进行计数,如果出现T中的有效字符count + 1
;不断移动right指针,直到count与T.len
相等。 public String minWindow(String s, String t) {
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0; i < t.length(); i++) {// 构造t的Hashmap
char ch = t.charAt(i);
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
int left = 0;
int right = 0;
int count = 0;
String result = "";
while (right < s.length()) {// 如果right=s.len,说明到最后一个字母时,没有找到最小覆盖子串,不用再找了
char ch1 = s.charAt(right);
// 当前的字母次数减一,一定得是字母在Hashmap中,即是t中的字母
if (map.containsKey(ch1)) {
map.put(ch1, map.get(ch1) - 1);
//代表当前符合了一个字母
if (map.get(ch1) >= 0) {
count++;
}
}
while (count == t.length()) {// 只要count仍然为t.len,就可以尝试不断右移left压缩窗口
if (result.equals("")) {
result = s.substring(left, right + 1);
} else if (result.length() > (right - left + 1)) {
result = s.substring(left, right + 1);
}
char ch2 = s.charAt(left);
// 因为要把当前字母移除,所以相应次数要加 1
if (map.containsKey(ch2)) {
map.put(ch2, map.get(ch2) + 1);
if (map.get(ch2) > 0) { //此时的 map[key] 大于 0 了,表示缺少当前字母了,count--
count--;
}
}
left++;
}
right++;
}
return result;
}
输入: nums = [1,2,3]
输出: [
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
result.add(new ArrayList<>());
if (nums.length == 0) {
return result;
}
for (int i = 1; i <= nums.length; i++) {
List<Integer> item = new ArrayList<>();
backtrace(nums, i, item, result, 0);
}
return result;
}
public void backtrace(int[] nums, int len, List<Integer> item, List<List<Integer>> result, int start) {
if (item.size() == len) {
result.add(new ArrayList<>(item));
return;
}
for (int i = start; i < nums.length; i++) {
item.add(nums[i]);
backtrace(nums, len, item, result, i + 1);
item.remove(item.size() - 1);
}
}
1 2 3
0 0 0 -> [ ]
0 0 1 -> [ 1]
0 1 0 -> [ 2 ]
0 1 1 -> [ 2 1]
1 0 0 -> [3 ]
1 0 1 -> [3 1]
1 1 0 -> [3 2 ]
1 1 1 -> [3 2 1]
public List<List<Integer>> subsets(int[] nums) {
int times = (int) Math.pow(2, nums.length);
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < times; i++) {
int temp = i;
List<Integer> list = new ArrayList<>();
int count = 0;// 记录要添加的是哪一位
while (temp != 0) {
if ((temp & 1) == 1) {// 判断待添加位是否为1
list.add(nums[count]);
}
temp = temp >> 1; // 右移一位,继续判断下一个待添加位
count++;// 指向下一个要添加的位置
}
result.add(list);
}
return result;
}
board =
[
['A','B','C','E']
,
['S','F','C','S']
,
['A','D','E','E']
]
给定 word = “ABCCED”, 返回 true.
给定 word = “SEE”, 返回 true.
给定 word = “ABCB”, 返回 false.
public boolean exist(char[][] board, String word) {
boolean[][] visited = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (word.charAt(0) == board[i][j] && backtrace(i, j, 0, word, board, visited)) {
return true;
}
}
}
return false;
}
public boolean backtrace(int i, int j, int cur, String word, char[][] bord, boolean[][] visited) {
if (cur == word.length()) {
return true;
}
if (i < 0 || j < 0 || i >= bord.length || j >= bord[0].length
|| visited[i][j] || word.charAt(cur) != bord[i][j]) {
return false;
}
visited[i][j] = true;
if (backtrace(i - 1, j, cur + 1, word, bord, visited) || backtrace(i + 1, j, cur + 1, word, bord, visited)
|| backtrace(i, j - 1, cur + 1, word, bord, visited) || backtrace(i, j + 1, cur + 1, word, bord, visited)) {
return true;
}
visited[i][j] = false;
return false;
}
输入: [2,1,5,6,2,3]
输出: 10
(j - i + 1)
作为矩形的长,计算出当前矩形的面积,并更新max_area;public int largestRectangleArea(int[] heights) {
int area = 0;
for (int i = 0; i < heights.length; i++) {
int min = heights[i];
for (int j = i; j < heights.length; j++) {
if (min > heights[j]) {
min = heights[j];
}
int temp_area = (j - i + 1) * min;
if (area < (j - i + 1) * min) {
area = temp_area;
}
}
}
return area;
}
末尾处加了一个0
,就是为了让面积能在最后结束结算。因此循环时,i的上限为heights.len
。public int largestRectangleArea(int[] heights) {
int area = 0;
Stack<Integer> stack = new Stack<>();
for (int i = 0; i <= heights.length; i++) {
int h = (i == heights.length) ? 0 : heights[i];
if (stack.isEmpty() || h >= heights[stack.peek()]) {
stack.push(i);
} else {
int temp = stack.pop();
area = Math.max(area, heights[temp] * (stack.isEmpty() ? i : i - 1 - stack.peek()));
i--;
}
}
return area;
}