leetcode-954. 二倍数对数组
leetcode-954. 二倍数对数组
- 题源
- 知识点
- 思路
- 代码
- python
- javascript
- java
- C
题源
- 954. 二倍数对数组
知识点
- 哈希表
- 对于哈希表,我有了新认识,以前我感觉
哈希是哈希,数组是数组
,虽然现在我也是这样理解的;但是我发现哈希表也是通过索引来查找的,和数组的查找差不多,只不过数组中的索引只能是大于登录0的整数
,而哈希表中即可以满足大于登录0的整数的数组特性,还可以是其他类型的数
。哈希中的索引是通过哈希算法得到的。
- 对于哈希表,我有了新认识,以前我感觉
- 排序
- 对于这道题目来说,排序也至关重要,因为解决此题,遍历的顺序尤为重要。而这里排序的是哈希的键,而非输入的数组。
思路
- 这一题其实也就是问,能不能分成n/2对的元素,且每一对的元素相差一倍即(value1 = 2 * value2)
- 思路
- 先将
数组转化为哈希表
。 - 单独考虑
哈希表中0的个数
是否符合条件。- 如果0的个数为
奇数
,则不满足条件返回假(false)
。 - 如果0的个数为
偶数
,则满足条件,继续执行
下面的代码。
- 如果0的个数为
- 对哈希表中的key进行
绝对值的排序
。 - 对拍好序的哈希表中的
key进行遍历
。- 如果哈希表中的key的个数
大于
哈希表中的2 *key 的个数则返回假(false)
。 - 哈希表中的2 *key的个数
等于
哈希表中的2 *key的个数减哈希表中的key的个数。
- 如果哈希表中的key的个数
- 成功遍历成功,
返回真(true)
。
- 先将
代码
python
- 第一个是直接用字典写的,第二个是用collections模块中的Counter写的。
- python写代码过程的总结:
- 字典用此方式
[key]
访问一个没有存在的key的值会报错
。 .get(key)
方法访问一个没有存在的key的值默认返回None,如果需要更改默认返回需加第二个参数,如默认返回1
,.get(key, 1)
。- .setdefault(key, value)设置key的默认值为value,如果改字典存在该key,则此方法失效。
- collections模块中的Counter(arr)就是统计arr中元素的个数。并且可以通过
[key]
访问,并且就算访问一个没有存在的key的值也不会报错
,默认返回0
。
- 字典用此方式
class Solution:def canReorderDoubled(self, arr: list[int]) -> bool:arr_dict = self.arrToDict(arr) # 将数组转换为字典或者说是哈希化if arr_dict.get(0, 0) % 2 == 1:# 单独判断数组中0的个数return Falsefor key in sorted(arr_dict, key=abs):if arr_dict.get(key, 0) > arr_dict.get(2 * key, 0):return Falsearr_dict[2 * key] = arr_dict.get(2 * key, 0) - arr_dict.get(key, 0)return Truedef arrToDict(self, arr: list[int]) -> list[int]:re = {}for num in arr:re.setdefault(num, 0)re[num] += 1return re
执行用时:104 ms, 在所有 Python3 提交中击败了79.72%的用户
内存消耗:17.1 MB, 在所有 Python3 提交中击败了37.06%的用户
import collections as csclass Solution:def canReorderDoubled(self, arr: List[int]) -> bool:arr_dict = cs.Counter(arr)if arr_dict[0] % 2 == 1:return Falsefor key in sorted(arr_dict, key=abs):if arr_dict[key] > arr_dict[2 * key]:return Falsearr_dict[2 * key] -= arr_dict[key]return True
执行用时:100 ms, 在所有 Python3 提交中击败了79.72%的用户
内存消耗:17 MB, 在所有 Python3 提交中击败了50.35%的用户
javascript
- javascript写代码过程的总结:
- Map()和对象的差异
Map.prototype.get或者set
会重写
默认的方法,并且遍历的时候不会出现重写的方法,如果你Map.prototype.asd等自定义
的方法时候,你通过for in 遍历map的时候会把自定义的方法命遍历出来
。- map和对象访问
不存在的key
时,不会报错,而是会返回undefined
。
/*** @param {number[]} arr* @return {boolean}*/
var canReorderDoubled = function(arr) {let arrMap = arrToMap(arr)if(arrMap.get(0) % 2 === 1) return falsefor(let key of mapSort(arrMap)){if(arrMap.get(key) > arrMap.get(2 * key)) return falsearrMap[2 * key] = arrMap.get(2 * key) - arrMap.get(key)}return true
};const arrToMap = (arr) => {let re = new Map()Map.prototype.get = function(key){if(this[key] === undefined) return 0return this[key]}Map.prototype.set = function(key){if(this[key] === undefined) this[key] = 1else this[key]++}for(let num of arr) re.set(num)return re
}const mapSort = (map) =>{let arr = []for(let key in map) arr.push(key)return arr.sort((a, b) => Math.abs(a) - Math.abs(b))
}
执行用时:124 ms, 在所有 JavaScript 提交中击败了60.00%的用户
内存消耗:47.8 MB, 在所有 JavaScript 提交中击败了60.00%的用户
java
- 对java确实不够熟悉,总共写了5次才过。
- java写代码过程的总结:
- if语句中只写一个
只能用布尔类型(真假)
,如果用其他类型则需要用运算符
(!=、==等)。 map.getOrDefault(key, defaultValue)
就是当key不存在时,返回defaultValue,存在则返回当前key的值。map.keySet()获取的键值
,需要重新赋值
给其他对象,如List集合,之后再进行相应的操作。Collections.sort(list, cmp)
进行排序。
- if语句中只写一个
class Solution {public boolean canReorderDoubled(int[] arr) {Map<Integer, Integer> map = Solution.arrToMap(arr);if(map.getOrDefault(0, 0) % 2 == 1) return false;List<Integer> list = new ArrayList<>();for(int num : map.keySet()) list.add(num);Collections.sort(list, (a, b) -> Math.abs(a) - Math.abs(b));for(int key : list){int key1Count = map.getOrDefault(key, 0);int key2Count = map.getOrDefault(key * 2, 0);if(key1Count > key2Count) return false;map.replace(2 * key, key2Count - key1Count);}return true;}public static Map<Integer, Integer> arrToMap(int[] arr){Map<Integer, Integer> map = new HashMap<>();for(int key : arr){if(map.containsKey(key)) map.replace(key, map.get(key) + 1);else map.put(key, 1);}return map;}
}
执行用时:28 ms, 在所有 Java 提交中击败了89.17%的用户
内存消耗:49.1 MB, 在所有 Java 提交中击败了10.30%的用户
C
- 对C哈希参考文献
- 仲一.C语言哈希表uthash的使用方法详解.知乎
- aclove.uthash详解.博客园
- Troy D. Hanson.uthash下载链接.github
- 对C的总结:
- 使用uthash中其实也是用了
双向链表
,故每一次添加map的地址都会变化
,故我写函数的时候,需要返回当前位置。 - 自己写的函数效率不高。
- 下面是uthash的常用方法。
- 使用uthash中其实也是用了
HASH_ADD_INT(map, key, temp); //key为你自己定义结构体key的名字,为添加的结构体temp
HASH_FIND_INT(map, &one, find); //找不到返回NULL
HASH_REPLACE_INT(map, key, newtemp1, temp); // 替换
HASH_DEL(map, newtemp1); // 删除
HASH_CLEAR(hh, map);// 清空
int HASH_COUNT(map) // 返回int类型,个数
HASH_SORT( users, name_sort ); // 排序
- 程序代码
typedef struct{ // C语言哈希结构体int key;int value;UT_hash_handle hh; // 这个就是必写
}Map;int get(Map *map, int key){ // get函数,如果存在则返回相应的int值,如果不存在则返回0Map *result;HASH_FIND_INT(map, &key, result);if(result == NULL) return 0;else return result->value;
}bool find(Map *map, int key){ // find函数,存在则为true,不存在则返回falseMap *result;HASH_FIND_INT(map, &key, result);if(result == NULL) return false;else return true;
}Map* set(Map *map, int key, int value){ // set函数,设置键值Map *add = (Map *)malloc(sizeof(Map));add->key = key;add->value = value;if(find(map, key)){Map *old = (Map *)malloc(sizeof(Map));HASH_REPLACE_INT(map, key, add, old);} else HASH_ADD_INT(map, key, add);return map;
}Map* arrToMap(int *arr, int arrSize){ // 数组转化为map数据类型Map* map = (Map *)malloc(sizeof(Map));map = NULL;for(int i = 0; i < arrSize; i++){if(find(map, arr[i])) map = set(map, arr[i], get(map, arr[i]) + 1);else map = set(map, arr[i], 1);}return map;
}int *getKeys(Map *map, int *keysLen){ // 已数组形式返回哈希所有的键int *arr = (int *)malloc(sizeof(int) * HASH_COUNT(map));*keysLen = 0;Map *temp;for(temp = map; temp != NULL; temp = (Map *)temp->hh.next){arr[(*keysLen)++] = temp->key;}return arr;
}void mapPrintAll(Map *map){ // 遍历map的函数,在这道题目测试使用Map *temp;for(temp = map; temp != NULL; temp = (Map *)temp->hh.next){printf("%d: %d\n", temp->key, temp->value);}
}int cmp(const void *a, const void *b){ // qsort函数的比较函数return abs(*((int *)a)) - abs(*((int *)b));
}bool canReorderDoubled(int* arr, int arrSize){Map* map = arrToMap(arr, arrSize);int *keysLen = (int *)malloc(sizeof(int));int *keys = getKeys(map, keysLen);qsort(keys, *keysLen, sizeof(int), cmp);for(int i = 0; i < *keysLen; i++){if(get(map, keys[i]) > get(map, 2 * keys[i])) return false;set(map, 2 * keys[i], get(map, 2 * keys[i]) - get(map, keys[i])); } return true;
}
执行用时:196 ms, 在所有 C 提交中击败了5.71%的用户
内存消耗:85.8 MB, 在所有 C 提交中击败了5.72%的用户
leetcode-954. 二倍数对数组相关推荐
- leetcode:954. 二倍数对数组
954. 二倍数对数组 来源:力扣(LeetCode) 链接: https://leetcode-cn.com/problems/array-of-doubled-pairs/ 给定一个长度为偶数的整 ...
- LeetCode 954. 二倍数对数组(map计数)
文章目录 1. 题目 2. 解题 1. 题目 给定一个长度为偶数的整数数组 A,只有对 A 进行重组后可以满足 对于每个 0 <= i < len(A) / 2,都有 A[2 * i + ...
- LeetCode 954. 二倍数对数组
题目链接: 力扣https://leetcode-cn.com/problems/array-of-doubled-pairs/ [分析]通过哈希表和排序来解决这个问题,先统计0的个数,因为0这个元素 ...
- Javascript(JS) leetcode 954. 二倍数对数组
给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 * ...
- 《LeetCode刷题》954. 二倍数对数组(java篇)
题目描述: 给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] ...
- leetcode 954. Array of Doubled Pairs | 954. 二倍数对数组(Java)
题目 https://leetcode.com/problems/array-of-doubled-pairs/ 题解 对于每一个数n来说,它要么和 n / 2 凑一对,要么和 n * 2 凑一对. ...
- LeetCode中等题之二倍数对数组
题目 给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 ...
- leetcode954. 二倍数对数组(treemap)
给定一个长度为偶数的整数数组 A,只有对 A 进行重组后可以满足 "对于每个 0 <= i < len(A) / 2,都有 A[2 * i + 1] = 2 * A[2 * i] ...
- leetcode954.二倍数对数组C++(绝对值排序)
链接: https://leetcode-cn.com/problems/array-of-doubled-pairs/ 描述和示例: 代码: class Solution {public:bool ...
最新文章
- centos6 安装 mantisbt-1.2.8 —— (3)Linux系统下yum源配置(Centos 6)
- 数据中心的“维稳之道”
- 关于获取网络流,根据网络流转byte[],本地文件流转byte[],方法记录
- 利用计算机进行绘制建筑图纸,工程计算机制图.pdf
- fiddler4使用教程
- 方方格子补丁_方方格子Excel工具箱WPS版本-方方格子(WPS版)附注册文件补丁下载V3.2.6.0测试版-西西软件下载...
- php 精准定位到街道,ip地址查询精确到街道_ip查询详细地址带地图
- pmp 第六版 模拟卷3疑难问题
- Excel批量随机生成姓名
- 冯乐乐之二 shader的数学
- (伪)点到线段的距离 C++
- 开源中国众包第三波阿里云悬赏项目,总金额 6 万
- python毕业设计题目推荐汽车销售系统
- OpenWRT 设置脚本自动更新hosts访问不可描述的站点
- windows蓝屏代码含意全集
- 顺序表的具体使用方法.数据解构(二)
- 那些有趣的网站系列(十)
- 【数据结构】赫夫曼树与编码
- Python模块:Re模块、附软件开发目录规范
- OpenMV 线性回归巡线之一:赛道提取
热门文章
- 月入3000万 估值一亿美金的微信公众号
- 查看oracle11g的企业管理器(OEM)
- 【CV】斯坦福CS231n DL-CV by李飞飞 team
- linux编译c如何延时,linux和windows下,C/C++开发的延时函数,sleep函数
- 考研由考生编号估计学校,报考人数和专业
- android+imei+为null,适合Android7.0以上(到9.0)系统,获取 关于手机--状态信息 (如:MAC,IMEI,IMSI,ICCID)...
- 黑马旅游网-旅游分类线路分页显示(七)
- python爬虫微博热搜_Python网络爬虫之爬取微博热搜
- 2-3树与2-3-4树
- 百度paddlepaddle七天打卡之青你实战