TypeScript & Map & Set All In One
Map & Set
var Map: MapConstructor
new <number, number>(iterable?: Iterable<readonly [number, number]> | null | undefined) => Map<number, number> (+3 overloads)
var Set: SetConstructor
new <number>(iterable?: Iterable<number> | null | undefined) => Set<number> (+1 overload)
Generic
/// <reference no-default-lib="true"/>
interface Map<K, V> {
clear(): void;
/**
* @returns true if an element in the Map existed and has been removed, or false if the element does not exist.
*/
delete(key: K): boolean;
/**
* Executes a provided function once per each key/value pair in the Map, in insertion order.
*/
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
/**
* Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
* @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
*/
get(key: K): V | undefined;
/**
* @returns boolean indicating whether an element with the specified key exists or not.
*/
has(key: K): boolean;
/**
* Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
*/
set(key: K, value: V): this;
/**
* @returns the number of elements in the Map.
*/
readonly size: number;
}
interface MapConstructor {
new(): Map<any, any>;
new <K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;
readonly prototype: Map<any, any>;
}
declare var Map: MapConstructor;
interface Set<T> {
/**
* Appends a new element with a specified value to the end of the Set.
*/
add(value: T): this;
clear(): void;
/**
* Removes a specified value from the Set.
* @returns Returns true if an element in the Set existed and has been removed, or false if the element does not exist.
*/
delete(value: T): boolean;
/**
* Executes a provided function once per each value in the Set object, in insertion order.
*/
forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
/**
* @returns a boolean indicating whether an element with the specified value exists in the Set or not.
*/
has(value: T): boolean;
/**
* @returns the number of (unique) elements in Set.
*/
readonly size: number;
}
interface SetConstructor {
new <T = any>(values?: readonly T[] | null): Set<T>;
readonly prototype: Set<any>;
}
declare var Set: SetConstructor;
https://www.typescriptlang.org/docs/handbook/generics.html
https://www.typescriptlang.org/docs/handbook/2/generics.html
demos
~~
double not bitwise / 双非位运算符
, 等价于 Math.floor
的功能 向下取整
✅
双非位运算符的妙用:~~undefined
=> 0
, 可以用于处理字符串的大数相加,避免出现 parseInt(undefined)
=> NaN
bug ❌
parseInt(undefined)
NaN
parseInt(~~undefined)
0
parseInt(NaN)
NaN
parseInt(null)
NaN
parseInt(``)
NaN
parseInt(false)
NaN
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT
"use strict";
/**
*
* @author xgqfrms
* @license MIT
* @copyright xgqfrms
* @created 2022/03/11
* @modified 2023-02-23
*
* @description 229. Majority Element II
* @description 229. 多数元素 II
* @difficulty Medium
* @ime_complexity O(n)
* @space_complexity O(n)
* @augments
* @example
* @link https://leetcode.com/problems/majority-element-ii/
* @link https://leetcode.cn/problems/majority-element-ii/
* @solutions
*
* @best_solutions
*
*/
// export {};
const log = console.log;
function majorityElement(nums: number[]): number[] {
// const base = Math.floor(nums.length / 3);
// ~~ double not bitwise / 双非位运算符, 等价于 Math.floor 的功能向下取整 ✅
// 双非位运算符的妙用:~~undefined => 0, 可以用于处理字符串的大数相加,避免出现 parseInt(undefined) => NaN bug ❌
/*
parseInt(undefined)
NaN
parseInt(~~undefined)
0
parseInt(NaN)
NaN
parseInt(null)
NaN
parseInt(``)
NaN
parseInt(false)
NaN
*/
const base = ~~(nums.length / 3);
const map = new Map<number, number>();
const set = new Set<number>();
for(const num of nums) {
if(!map.has(num)) {
map.set(num, 1);
} else {
map.set(num, (map.get(num) ?? 0) + 1);
}
if((map.get(num) ?? 0) > base) {
set.add(num);
}
}
return [...set];
};
// function majorityElement(nums: number[]): number[] {
// const base = ~~(nums.length / 3);
// const map = new Map<number, number>();
// const set = new Set<number>();
// for(const num of nums) {
// if(!map.has(num)) {
// map.set(num, 1);
// } else {
// map.set(num, map.get(num) + 1);
// }
// if(map.get(num) > base) {
// set.add(num);
// }
// }
// return [...set];
// };
// function majorityElement(nums: number[]): number[] {
// const base = ~~(nums.length / 3);
// const map = new Map();
// for(const num of nums) {
// if(!map.has(num)) {
// map.set(num, 1);
// } else {
// map.set(num, map.get(num) + 1);
// }
// }
// return [...map.entries()].filter(([_, v]) => v > base).map(([k, _]) => k);
// return [...map.values()].filter(v) => v > base);
// return [...map.keys()].filter(k) => k > base);
// };
// 测试用例 test cases
const testCases = [
{
input: [3,2,3],
result: [3],
desc: 'value equal to [3]',
},
{
input: [1],
result: [1],
desc: 'value equal to [1]',
},
{
input: [1,2],
result: [1,2],
desc: 'value equal to [1,2]',
},
];
for (const [i, testCase] of testCases.entries()) {
const result = majorityElement(testCase.input);
log(`test case ${i} result: `, JSON.stringify(result) === JSON.stringify(testCase.result) ? `✅ passed` : `❌ failed`, result);
}
// $ npx ts-node ./229\ majority-element-ii.ts
/*
test case 0 result: ✅ passed [ 3 ]
test case 1 result: ✅ passed [ 1 ]
test case 2 result: ✅ passed [ 1, 2 ]
*/
https://leetcode.com/problems/majority-element-ii/