leetcode-954. 二倍数对数组

  • 题源
  • 知识点
  • 思路
  • 代码
    • python
    • javascript
    • java
    • C

题源

  • 954. 二倍数对数组

知识点

  • 哈希表

    • 对于哈希表,我有了新认识,以前我感觉哈希是哈希,数组是数组,虽然现在我也是这样理解的;但是我发现哈希表也是通过索引来查找的,和数组的查找差不多,只不过数组中的索引只能是大于登录0的整数,而哈希表中即可以满足大于登录0的整数的数组特性,还可以是其他类型的数。哈希中的索引是通过哈希算法得到的。
  • 排序
    • 对于这道题目来说,排序也至关重要,因为解决此题,遍历的顺序尤为重要。而这里排序的是哈希的键,而非输入的数组。

思路

  • 这一题其实也就是问,能不能分成n/2对的元素,且每一对的元素相差一倍即(value1 = 2 * value2)
  • 思路
    • 先将数组转化为哈希表
    • 单独考虑哈希表中0的个数是否符合条件。
      • 如果0的个数为奇数,则不满足条件返回假(false)
      • 如果0的个数为偶数,则满足条件,继续执行下面的代码。
    • 对哈希表中的key进行绝对值的排序
    • 对拍好序的哈希表中的key进行遍历
      • 如果哈希表中的key的个数大于哈希表中的2 *key 的个数则返回假(false)
      • 哈希表中的2 *key的个数等于哈希表中的2 *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)进行排序。
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的常用方法。
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. 二倍数对数组相关推荐

  1. leetcode:954. 二倍数对数组

    954. 二倍数对数组 来源:力扣(LeetCode) 链接: https://leetcode-cn.com/problems/array-of-doubled-pairs/ 给定一个长度为偶数的整 ...

  2. LeetCode 954. 二倍数对数组(map计数)

    文章目录 1. 题目 2. 解题 1. 题目 给定一个长度为偶数的整数数组 A,只有对 A 进行重组后可以满足 对于每个 0 <= i < len(A) / 2,都有 A[2 * i + ...

  3. LeetCode 954. 二倍数对数组

    题目链接: 力扣https://leetcode-cn.com/problems/array-of-doubled-pairs/ [分析]通过哈希表和排序来解决这个问题,先统计0的个数,因为0这个元素 ...

  4. Javascript(JS) leetcode 954. 二倍数对数组

    给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 * ...

  5. 《LeetCode刷题》954. 二倍数对数组(java篇)

    题目描述: 给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] ...

  6. leetcode 954. Array of Doubled Pairs | 954. 二倍数对数组(Java)

    题目 https://leetcode.com/problems/array-of-doubled-pairs/ 题解 对于每一个数n来说,它要么和 n / 2 凑一对,要么和 n * 2 凑一对. ...

  7. LeetCode中等题之二倍数对数组

    题目 给定一个长度为偶数的整数数组 arr,只有对 arr 进行重组后可以满足 "对于每个 0 <= i < len(arr) / 2,都有 arr[2 * i + 1] = 2 ...

  8. leetcode954. 二倍数对数组(treemap)

    给定一个长度为偶数的整数数组 A,只有对 A 进行重组后可以满足 "对于每个 0 <= i < len(A) / 2,都有 A[2 * i + 1] = 2 * A[2 * i] ...

  9. leetcode954.二倍数对数组C++(绝对值排序)

    链接: https://leetcode-cn.com/problems/array-of-doubled-pairs/ 描述和示例: 代码: class Solution {public:bool ...

最新文章

  1. centos6 安装 mantisbt-1.2.8 —— (3)Linux系统下yum源配置(Centos 6)
  2. 数据中心的“维稳之道”
  3. 关于获取网络流,根据网络流转byte[],本地文件流转byte[],方法记录
  4. 利用计算机进行绘制建筑图纸,工程计算机制图.pdf
  5. fiddler4使用教程
  6. 方方格子补丁_方方格子Excel工具箱WPS版本-方方格子(WPS版)附注册文件补丁下载V3.2.6.0测试版-西西软件下载...
  7. php 精准定位到街道,ip地址查询精确到街道_ip查询详细地址带地图
  8. pmp 第六版 模拟卷3疑难问题
  9. Excel批量随机生成姓名
  10. 冯乐乐之二 shader的数学
  11. (伪)点到线段的距离 C++
  12. 开源中国众包第三波阿里云悬赏项目,总金额 6 万
  13. python毕业设计题目推荐汽车销售系统
  14. OpenWRT 设置脚本自动更新hosts访问不可描述的站点
  15. windows蓝屏代码含意全集
  16. 顺序表的具体使用方法.数据解构(二)
  17. 那些有趣的网站系列(十)
  18. 【数据结构】赫夫曼树与编码
  19. Python模块:Re模块、附软件开发目录规范
  20. OpenMV 线性回归巡线之一:赛道提取

热门文章

  1. 月入3000万 估值一亿美金的微信公众号
  2. 查看oracle11g的企业管理器(OEM)
  3. 【CV】斯坦福CS231n DL-CV by李飞飞 team
  4. linux编译c如何延时,linux和windows下,C/C++开发的延时函数,sleep函数
  5. 考研由考生编号估计学校,报考人数和专业
  6. android+imei+为null,适合Android7.0以上(到9.0)系统,获取 关于手机--状态信息 (如:MAC,IMEI,IMSI,ICCID)...
  7. 黑马旅游网-旅游分类线路分页显示(七)
  8. python爬虫微博热搜_Python网络爬虫之爬取微博热搜
  9. 2-3树与2-3-4树
  10. 百度paddlepaddle七天打卡之青你实战