方法:双指针+逆序
归并排序中归并的思路
public class Solution {
public void merge(int A[], int m, int B[], int n) {
int k = m + n - 1;
int i = m - 1, j = n - 1;
while (i >= 0 || j >= 0) {
if (i < 0) {
A[k--] = B[j--];
} else if (j < 0) {
break;
} else if (A[i] > B[j]) {
A[k--] = A[i--];
} else {
A[k--] = B[j--];
}
}
}
}
方法一:双指针
public class Solution {
public boolean judge (String str) {
int i = 0, j = str.length() - 1;
while (i < j && str.charAt(i) == str.charAt(j)) {
i++;
j--;
}
return i >= j;
}
}
方法一:自定义排序
/*
* public class Interval {
* int start;
* int end;
* public Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
public ArrayList<Interval> merge (ArrayList<Interval> intervals) {
ArrayList<Interval> res = new ArrayList<Interval>();
if (intervals == null || intervals.size() == 0) return res;
Collections.sort(intervals, (a, b) -> a.start - b.start);
res.add(intervals.get(0));
for (int i = 1; i < intervals.size(); i++) {
Interval cur = intervals.get(i);
Interval pre = res.get(res.size() - 1);
if (pre.end >= cur.start) {
pre.end = Math.max(pre.end, cur.end);
} else {
res.add(cur);
}
}
return res;
}
}
滑动窗口
public class Solution {
Map<Character, Integer> std = new HashMap<>();
Map<Character, Integer> cnt = new HashMap<>();
public String minWindow (String S, String T) {
for (char c : T.toCharArray()) {
std.put(c, std.getOrDefault(c, 0) + 1);
}
int le = 0, ri = 0;
int minLen = S.length() + 1, L = -1, R = -1;
while (ri < S.length()) {
// 只统计T中需要的字符
if (std.containsKey(S.charAt(ri))) {
cnt.put(S.charAt(ri), cnt.getOrDefault(S.charAt(ri), 0) + 1);
}
while (check() && le <= ri) {
if (ri - le + 1 < minLen) {
minLen = ri - le + 1;
L = le;
R = ri;
}
if (cnt.containsKey(S.charAt(le))) {
cnt.put(S.charAt(le), cnt.getOrDefault(S.charAt(le), 0) - 1);
}
le++;
}
ri++;
}
return L == -1 ? "" : S.substring(L, R + 1);
}
private boolean check() {
Iterator iter = std.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Character key = (Character) entry.getKey();
Integer val = (Integer) entry.getValue();
if (cnt.getOrDefault(key, 0) < val) {
return false;
}
}
return true;
}
}
方法一:StringBuffer().reverse()(15ms)
public class Solution {
public String solve (String str) {
return new StringBuffer(str).reverse().toString();
}
}
方法二:双指针(18ms)
public class Solution {
public String solve (String str) {
int n = str.length();
char[] res = new char[n];
for (int i = 0; i < n; i++) {
res[i] = str.charAt(n - i - 1);
}
return new String(res);
}
}
方法一:双指针+HashSet
public class Solution {
public int maxLength (int[] arr) {
int res = 0;
Set<Integer> set = new HashSet<>();
for (int le = 0, ri = 0; ri < arr.length; ri++) {
while (le < ri && set.contains(arr[ri])) {
set.remove(arr[le]);
le++;
}
res = Math.max(res, ri - le + 1);
set.add(arr[ri]);
}
return res;
}
}
方法一:暴力法(超时(13/15)
public class Solution {
public int maxArea (int[] height) {
int res = 0;
for (int i = 0; i < height.length; i++) {
for (int j = i + 1; j < height.length; j++) {
res = Math.max(res, (j - i) * Math.min(height[i], height[j]));
}
}
return res;
}
}
方法二:双指针(199ms)
public class Solution {
public int maxArea (int[] height) {
int res = 0;
int le = 0, ri = height.length - 1;
while (le <= ri) {
if (height[le] < height[ri]) {
res = Math.max(res, height[le] * (ri - le));
le++;
} else {
res = Math.max(res, height[ri] * (ri - le));
ri--;
}
}
return res;
}
}
方法一:暴力法、运行超时(8/11)
public class Solution {
public long maxWater (int[] arr) {
if (arr == null || arr.length < 3) return 0;
int n = arr.length;
long res = 0;
for (int i = 1; i < n - 1; i++) {
int leftMax = 0, rightMax = 0;
for (int j = i - 1; j >= 0; j--) {
leftMax = Math.max(leftMax, arr[j]);
}
for (int j = i + 1; j < n; j++) {
rightMax = Math.max(rightMax, arr[j]);
}
res += Math.max(0, Math.min(leftMax, rightMax) - arr[i]);
}
return res;
}
}
方法二:空间换时间(301ms)
public class Solution {
public long maxWater (int[] arr) {
if (arr == null || arr.length < 3) return 0;
int n = arr.length;
int[] leftMax = new int[n];
int[] rightMax = new int[n];
leftMax[0] = arr[0];
for (int i = 1; i < n; i++) leftMax[i] = Math.max(leftMax[i - 1], arr[i]);
rightMax[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--) rightMax[i] = Math.max(rightMax[i + 1], arr[i]);
long res = 0;
for (int i = 1; i < n - 1; i++) {
res += (long)Math.max(0, Math.min(leftMax[i - 1], rightMax[i + 1]) - arr[i]);
}
return res;
}
}
方法三:双指针(306ms)
public class Solution {
public long maxWater (int[] arr) {
if (arr == null || arr.length < 3) return 0;
long res = 0;
int le = 1, ri = arr.length - 2;
int leftMax = arr[0], rightMax = arr[arr.length - 1];
while (le <= ri) {
if (leftMax < rightMax) {
res += Math.max(0, leftMax - arr[le]);
leftMax = Math.max(leftMax, arr[le++]);
} else {
res += Math.max(0, rightMax - arr[ri]);
rightMax = Math.max(rightMax, arr[ri--]);
}
}
return res;
}
}