62,628
社区成员
发帖
与我相关
我的任务
分享
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Integer> list=new ArrayList<Integer>();
for(int i=1;i<2021;i++)list.add(i);
while(list.size()>1) {
for(int i=0;i<list.size();i++) {
if(i%4!=1) {
list.remove(i);
}
}
}
System.out.println(list.get(0));
}
}
public static void test1(int total) {
LinkedList<Integer> list = new LinkedList();
for(int i = 1; i <= total; i++) {
list.add(i);
}
for(int i = 1, idx = 0; list.size() > 1; i++, idx = idx == list.size() ? 0 : idx) {
if(i % 4 != 1)
list.remove(idx);
else
idx = ++idx;
}
System.out.println("val = " + list.get(0));
}
确实这种写法的效率很低,但是慢的不是链表,而是LinkedList,优化一下后效率会高很多,如果不考虑链表的初始化,效率一定会远高于数组。
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
public class LinkedListPlus<E> extends LinkedList<E>{
Node<E> first;
Node<E> last;
int size = 0;
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
last.next = first;
first.prev = last;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
public IteratorPlus<E> iterator() {
return new Itr();
}
public int size() {
return size;
}
private class Itr implements IteratorPlus<E> {
int cursor = 0;
private Node<E> thisNode;
public boolean hasNext() {
return cursor != size();
}
public E next() {
try {
int i = cursor;
E next = thisNode == null ? (thisNode = first).item : (thisNode = thisNode.next).item;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
public E removeThis() {
E v = this.thisNode.item;
Node<E> temp = this.thisNode.next;
Node<E> prev = this.thisNode.prev;
this.thisNode.prev.next = this.thisNode.next;
this.thisNode = temp;
this.thisNode.prev = prev;
size--;
//cursor--;
return v;
}
public void remove() {
}
public void resetCursor() {
cursor = 0;
}
}
public static interface IteratorPlus<E> extends Iterator{
public void resetCursor();
public E removeThis();
}
}
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import test.lt20.LinkedListPlus.IteratorPlus;
public class Test12 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int total = 15000000;
long time = System.currentTimeMillis();
fin(total);
time = System.currentTimeMillis();
System.out.println("--------");
test2(total);
System.out.println("数组总时间 = " + (System.currentTimeMillis() - time));
}
public static void test1(int total) {
LinkedList<Integer> list = new LinkedList();
for(int i = 1; i <= total; i++) {
list.add(i);
}
for(int i = 1, idx = 0; list.size() > 1; i++, idx = idx == list.size() ? 0 : idx) {
if(i % 4 != 1)
list.remove(idx);
else
idx = ++idx;
}
System.out.println("val = " + list.get(0));
}
public static void test2(int total) {
List<Integer> list = new ArrayList<>();
long time = System.currentTimeMillis();
for(int i= 1 ; i<=total;i++){
list.add(i);
}
System.out.println("数组初始化 = " + (System.currentTimeMillis() - time));
List<Integer> newList = test(list, 0);
System.out.println("val = " + newList.get(0));
}
public static List<Integer> test(List<Integer> list,int index){
List<Integer> newList = new ArrayList<>();
for (Integer i : list) {
if(index%4==0){
newList.add(i);
}
index ++;
}
//如果新集合为空 则上次集合的最后一位为最后剩下的一位
if(newList.size()==0){
newList.add(list.get(list.size()-1));
}
if(newList.size()==1){
return newList;
}
return test(newList,index);
}
public static void fin(int total) {
long time = System.currentTimeMillis();
LinkedListPlus<Integer> list = new LinkedListPlus<Integer>();
for(int i = 1; i <= total; i++) {
list.add(i);
}
System.out.println("链表初始化 = " + (System.currentTimeMillis() - time));
IteratorPlus<Integer> it = list.iterator();
time = System.currentTimeMillis();
boolean flag = it.hasNext();
int i = 0;
Integer temp = null;
if(flag) {
it.next();
do {
if(++i % 4 != 1) {
temp = it.removeThis();
}else {
it.next();
}
if(!(flag = it.hasNext())) {
it.resetCursor();
flag = it.hasNext();
}
} while (flag);
}
System.out.println("val = " + temp);
System.out.println("链表筛选 = " + (System.currentTimeMillis() - time));
}
}
链表初始化 = 13883
val = 3222785
链表筛选 = 412
--------
数组初始化 = 1306
val = 3222785
数组总时间 = 8339
还有一种更直观的解法是用队列(Queue),不过效率跟我写那个竟然一样,毕竟底层都是用的一个原理。
import java.util.LinkedList;
import java.util.Queue;
public class Test13 {
public static void main(String[] args) {
long time = System.currentTimeMillis();
doQueue(15000000);
System.out.println("队列总时间 = " + (System.currentTimeMillis() - time));
}
public static void doQueue(int total) {
Queue<Integer> queue = new LinkedList<Integer>();
for(int i = 1; i <= total; i++) {
queue.add(i);
}
int i = 0;
while(queue.size() > 1) {
if(++i % 4 == 1)
queue.add(queue.poll());
else
queue.poll();
}
System.out.println("val : " + queue.peek());
}
}
总结来说,虽然数组的测试速度要更快一些,但是频繁的创建大数组很可能是更糟糕的一件事,如果项目里真的有这种需求,我还是更倾向于使用链表。 public static void main(String[] args) {
// TODO Auto-generated method stub
List<Integer> list = new LinkedList();
for(int i = 0; i < 2020; i++) {
list.add(i);
}
for(int i = 1, idx = 1; list.size() > 1; i++, idx = idx == list.size() ? 0 : idx) {
if(i % 4 != 1)
list.remove(idx);
else
idx = ++idx;
}
System.out.println(list.get(0));
}public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for(int i= 1 ; i<=2020;i++){
list.add(i);
}
List<Integer> newList = test(list, 0);
System.out.println(newList.get(0));
}
public static List<Integer> test(List<Integer> list,int index){
List<Integer> newList = new ArrayList<>();
for (Integer i : list) {
if(index%4==0){
newList.add(i);
}
index ++;
}
//如果新集合为空 则上次集合的最后一位为最后剩下的一位
if(newList.size()==0){
newList.add(list.get(list.size()-1));
}
if(newList.size()==1){
return newList;
}
return test(newList,index);
}

其实我也懵逼, 这几天做codewars leetcode codinggame 人都傻了 太难了
