今日分析题目:
个人思路总结:
给你一个数组 nums ,请你完成两类查询。
其中一类查询要求 更新 数组 nums 下标对应的值
另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right
实现 NumArray 类:NumArray(int[] nums) 用整数数组 nums 初始化对象
void update(int index, int val) 将 nums[index] 的值 更新 为 val
int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], ..., nums[right])
这道题在数据量不大的情况下使用简单的暴力解法是没有问题的,但是操作频繁的话就会导致效率变慢,时间不符合要求。
对于大的东西全部的解法都是基于化整为零,将模块化成零散的,便于通过更新局部即可。
截取局部的方法也有许多种,下面是先分析官方提高的答案的解法细节:
分块,分块的原则是基于时间复杂度的,原则是将最大的复杂度时间降低,从而使得整体的开销减少,使性能提升,这个时候可以考虑的两个基本出发点就是时间复杂度和空间复杂度。
通过计算出空间复杂度和时间复杂度得出对应n的值(一个需要学习的思想)
954. 二倍数对数组 题目:
给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 “对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 * arr[2 * i]” 时,返回 true;否则,返回 false。
对于这种类型的算法题,首先需求确定几个地方:
1. 题目讲什么, 很容易受 “arr[2 * i + 1] = 2 * arr[2 * i]” 这个条件影响,但是实际上就是说一个问题而已,里面是否有值是相互的两倍。
2. 统计问题,如何统计一个值会更加的合理。可以使用一个数组,但是这样你不知道值的长度,这样会照成不必要的空间浪费,所以一个通用的方法 --- HashMap()。
create a HashMap() : Map<dataType, dataType> map = new HashMap<ataType, dataType>()
The follow is the ways which are used on this test
function name note put(key, value); In HashMap will not exist duplicate values. If exist will replace the key and value.
getOrDefault(key, defualValise) if the map value not exist will give bakc a default valuse map.keySet() get all key more detail we can see this link:Java HashMap | 菜鸟教程
I think it is important to learn about the hashMap.
When I can use the hashMap ?
1. need to search the value whether is on the List ? or array ?
2. use the filter the dupicalte data. Because the key is the only.
基于上述的点,接下来就是一些小细节,比如在hashMap中如何判断值是否存在。如何使用hashMap进行统计。还有很多,具体根据官方的答案进行小小的分析。
class Solution {
public boolean canReorderDoubled(int[] arr) {
Map<Integer, Integer> map = new HashMap<Integer,Integer>();
for(int x : arr){
map.put(x, map.getOrDefault(x, 0) + 1);
/**
why put the ket is getOrDefault?
Because this will make sure that the key is only one, the num in the arry
if the key is exist, the follow will add one.
it only one, the map valuse will only is one, or will bigger and this should return false;
*/
}
if(map.getOrDefault(0,0) %2 != 0){
return false;
}
/**
on this code I think it use to check the first num
but why the an odd number should be false
I think eg:
x = 0; if 2*arr[2*i] = 0; need another 0
and if the 0 is exist, It means should exist two 0;
If not the condition does not hold
*/
List<Integer> vals = new ArrayList<Integer>();
for(int x : map.keySet()){
vals.add(x);
}
/**
thie use a new list to store the map key
*/
Collections.sort(vals, (a,b) -> Math.abs(a) - Math.abs(b));
/**
ascending
*/
for(int x : vals){
if(map.getOrDefault(2*x,0) < map.get(x) ){
return false;
}
// this means the valuse is not arrage, or this key not exist
// or not enough 2x to pair wih x
map.put(2*x, map.getOrDefault(2*x,0) - map.get(x));
}
/**
map.getOrDefault(2*x,0) - map.get(x)
Because the 2*x should exist on the map and the key will bigger than or queal to 1; so we use this to reduce, so if the key is 0 means this key is not enough and could not use again
*/
return true;
}
}
。