Java List 拆解 - l00jj/algorithm GitHub Wiki
通过拆解 List 提速不一定需要完全拆解。 如 15. 三数之和 中,方法快慢并重要,方法 30ms 和 9ms 的解法都可以通过一重拆解达到 0ms 的目的;
所以重点在于尝试把计算环节放入size()中,在 2901. 最长相邻不相等子序列 II - 第 115 场双周赛 这题甚至只能放在 size() ,如果外置计算过程只能 size() 能加速至
import java.util.AbstractList;
class Solution {
List<List<Integer>> _ans = null;
public List<List<Integer>> threeSum(int[] nums) {
return new AbstractList<List<Integer>>(){
public List<Integer> get(int index){
return _ans.get(index);
}
public int size(){
init();
return _ans.size();
}
private void init(){
if(_ans != null) return;
final int n = nums.length;
_ans = new ArrayList<List<Integer>>();
int max = nums[0], min = nums[0];
for (int num : nums) {
if (max < num) max = num;
if (min > num) min = num;
}
int[] map = new int[max - min + 1];
int length = 0;
for (int num : nums) {
if (map[num-min]++ == 0) length++;
}
int[] list = new int[length];
int tail = 0;
for (int i = 0; i < map.length; i++) {
if (map[i] == 0) continue;
list[tail++] = i + min;
}
if (min > 0 || max < 0) return;
if (min <= 0 && map[-min] >= 3) {
List<Integer> res = new ArrayList(3);
res.add(0);
res.add(0);
res.add(0);
_ans.add(res);
}
for (int i = 0; i < length; i++) {
int num = list[i];
if (num >= 0) break;
if (map[num - min] > 1) {
int diff = -(num * 2);
if (diff - min < map.length) {
if (map[diff - min] > 0) {
List<Integer> res = new ArrayList(3);
res.add(num);
res.add(num);
res.add(diff);
_ans.add(res);
}
}
}
for (int j = i + 1; j < length; j++) {
int diff = -(num + list[j]);
if (diff - min >= map.length) continue;
if (diff < list[j]) break;
if (diff == list[j]) {
if (map[diff - min] > 1) {
List<Integer> res = new ArrayList(3);
res.add(num);
res.add(list[j]);
res.add(diff);
_ans.add(res);
}
} else {
if (map[diff - min] > 0) {
List<Integer> res = new ArrayList(3);
res.add(num);
res.add(list[j]);
res.add(diff);
_ans.add(res);
}
}
}
}
}
};
}
}class Solution extends java.util.AbstractList<List<Integer>> {
private static final AnsElement ANS_ELEMENT = new AnsElement();
private static final int[] EMPTY_TMPL = new int[1000];
private static final int[] CONTAINER = new int[1001];
private static int size;
private int[][] items1, items2;
private int pos = 1;
public List<List<Integer>> mergeSimilarItems(int[][] items1, int[][] items2) {
if (items1.length > items2.length) {
this.items1 = items1;
this.items2 = items2;
} else {
this.items1 = items2;
this.items2 = items1;
}
return this;
}
@Override
public List<Integer> get(int index) {
while (CONTAINER[pos] == 0) {
++pos;
}
ANS_ELEMENT.value = pos;
ANS_ELEMENT.weight = CONTAINER[pos];
CONTAINER[pos] = 0;
return ANS_ELEMENT;
}
@Override
public int size() {
if (items2 != null) {
if (size != 0) {
// 不是第一次调用,清空容器
System.arraycopy(EMPTY_TMPL, 0, CONTAINER, 0, size);
}
size = items1.length;
for (int[] item : items1) {
CONTAINER[item[0]] = item[1];
}
items1 = null;
for (int[] item : items2) {
if (CONTAINER[item[0]] == 0) {
// 初次记录
++size;
CONTAINER[item[0]] = item[1];
} else {
// 再次记录
CONTAINER[item[0]] += item[1];
}
}
items2 = null;
}
return size;
}
/** 答案元素 */
private static class AnsElement extends java.util.AbstractList<Integer> {
private int value, weight;
@Override
public Integer get(int index) {
return index == 0 ? value : weight;
}
@Override
public int size() {
return 2;
}
}
}