题目描述1
笔者解答1.1
class Solution {
public boolean canReorderDoubled(int[] A) {
List<Integer> IList=new LinkedList<Integer>();
int i;
int length=A.length;
for(i=0;i<length;i++){
IList.add(A[i]);
}
Collections.sort(IList,(o1,o2)->{
if(o1>o2){
if(o1<0)
return o2-o1;
else
return o1-o2;
}else{
if(o2<0)
return o2-o1;
else
return o1-o2;
}
});
for(i=0;i<length;i++){
System.out.println(IList.get(i));
}
while(IList.size()!=0){
int min_temp=IList.get(0);
IList.remove(0);
int double_temp=min_temp*2;
int left=0;
int right=IList.size();
boolean get=false;
while(left<right){
System.out.println();
int mid=(left+right)/2;
if(IList.get(mid)>double_temp){
right=mid;
}else if(IList.get(mid)<double_temp){
left=mid+1;
}else{
IList.remove(mid);
get=true;break;
}
}
if(left==right&&!get)
return false;
}
return true;
}
}
笔者分析1.2
这次代码只通过了一半多的用例,不是因为有BUG,而是思路错了,这里是不能用二分法的,因为整个序列不满足单调性。虽然在初始排序的时候控制了负数和正数的区别,但在while循环里还是用了二分法。当然可以不用二分法,既然都写到这了,直接比较就行,可是这样复杂度就高了,也意味着这种方法行不通。看了解答,用的是我不太熟悉的TreeMap,以前认为用的不多,没认真学,现在稍微整理一下。
class Solution {
public boolean canReorderDoubled(int[] A) {
int len = A.length;
if(len == 0){
return true;
}
int m, n;
Map<Integer, Integer> map = new TreeMap<>();
//把数组A每个元素的个数进行排序
for(int key : A){
map.put(key, map.getOrDefault(key, 0) + 1);
}
for(int key : map.keySet()){
if(map.get(key) == 0){
continue;
}
m = map.get(key);
if(key < 0){
key = key / 2;//比如-4在treemap中排在-2前面,所以是key/2
}else{
key = key * 2;//比如2在treemap中排在4前面,所以是key*2
}
n = map.getOrDefault(key, 0);
if(m > n){
return false;
}
map.put(key, n - m);
}
return true;
}
}
TreeMap或许不如HashMap那么常用,但它也有自己的应用场景,TreeMap可以实现元素的自动排序。TreeMap存储K-V键值对,通过红黑树(R-B tree)实现,也因为TreeMap是通过红黑树实现,红黑树结构天然支持排序,默认情况下通过Key值的自然顺序进行排序或者根据创建映射时提供的Comparator进行排序,具体取决于使用的构造方法。TreeMap的基本操作containsKey、get、put和remove的时间复杂度是log(n)。
- TreeMap是一个有序的key-value集合,它是通过红黑树实现的。
- TreeMap继承于AbstractMap,所以它是一个Map,即一个key-value集合。
- TreeMap实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
- TreeMap实现了Cloneable接口,意味着它能被克隆。
- TreeMap实现了java.io.Serializable接口,意味着它支持序列化。
遍历TreeMap的键值对
第一步:根据entrySet()获取TreeMap的“键值对”的set集合
第二步:通过Iterator迭代器遍历“第一步”得到的集合
Integer integ=null;
Iterator iter=map.entrySet().iterator();
while(iter.hasNext()){
Map.Entry entry=(Map.Entry)iter.next();
key=(String)entry.getKey();
integ=(Integer)entry.getValue();
}
遍历TreeMap的键
第一步:根据keySet()获取TreeMap的“键”的set集合
第二步:通过Iterator迭代器遍历“第一步”得到的集合
String key=null;
Integer integ=null;
Iterator iter=map.keySet().iterator();
while(iter.hasNext()){
key=(String)iter.next();
integ=(Integer)map.get(key);
}
遍历TreeMap的值
第一步:根据value()获取TreeMap的“值” 的集合
第二步:通过Iterator迭代器遍历“第一步”得到的集合
Integer value=null;
Collection c=map.values();
Iterator iter=c.iterator();
while(iter.hasNext()){
value=(Integer)iter.next();
}
总结
每日打卡十六天,以下图为证