這是第四周的練習題,五一放假結束,該收拾好狀態啦。前端
下面是以前分享的連接:git
本週練習內容:數據結構與算法 —— Set算法
這些都是數據結構與算法,一部分方法是團隊其餘成員實現的,一部分我本身作的,有什麼其餘實現方法或錯誤,歡迎各位大佬指點,感謝。數組
解題:
1.集合定義:
集合(Set)是一種包含不一樣元素的數據結構。集合中的元素稱爲成員,集合最重要的兩個特色:微信
即:無序且惟一。網絡
2.集合相關的數學概念:
集合的概念,如數學中一個由大於或等於0的整數組成的天然數集合, N = { 0, 1, 2, ...}
。
還有如空集,表示不包含任何元素的集合。
而且也有並集,交集,差集等操做。數據結構
add(value)
:向集合添加一個新的項。
delete(value)
:從集合移除一個值。
has(value)
:若是值在集合中,返回 true,不然返回 false。
clear()
:移除集合中的全部項。
size()
:返回集合所包含元素的數量。與數組的 length 屬性相似。
values()
:返回一個包含集合中全部值的數組。函數
解題:post
class Sets {
constructor(){
this.items = {}
}
has(value){
// return value in this.items
return this.items.hasOwnProperty(value)
}
add(value){
if(!this.has(value)) {
this.items[value] = value
return true
}
return false
}
delete(value){
if(!this.has(value)){
delete this.items[value]
return true
}
return false
}
clear(){
this.items = {}
}
size(){
const values = this.values()
return values.length
}
values(){
return Object.keys(this.items)
}
}
複製代碼
解題:
/** * union 並集 * @param {Object} otherSet 其餘集合 */
Sets.prototype.union = function(otherSet){
let result = new Sets(),
current = this.values(),
other = otherSet.values()
for(let i = 0; i < current.length; i++){
result.add(current[i])
}
for(let i = 0; i < other.length; i++){
result.add(other[i])
}
return result
}
/** * intersection 交集 * @param {Object} otherSet 其餘集合 */
Sets.prototype.intersection = function(otherSet){
let result = new Sets(),
current = this.values()
for(let i = 0; i < current.length; i++){
if(otherSet.has(current[i])){
result.add(current[i])
}
}
return result
}
/** * difference 差集 * @param {Object} otherSet 其餘集合 */
Sets.prototype.difference = function(otherSet){
let result = new Sets(),
current = this.values()
for(let i = 0; i < current.length; i++){
if(!otherSet.has(current[i])){
result.add(current[i])
}
}
return result
}
/** * subset 子集 * @param {Object} otherSet 其餘集合 */
Sets.prototype.subset = function(otherSet){
let result = new Sets(),
current = this.values()
if(this.size() > otherSet.size()) return false
for(let i = 0; i < current.length; i++){
if(!otherSet.has(current[i])){
return false
}
}
return true
}
複製代碼
使用示例以下:
const nums1 = [1, 2, 2, 1];
const nums2 = [2, 2];
const nums3 = [4, 9, 5];
const nums4 = [9, 4, 9, 8, 4];
intersection(nums1, nums2); // [2]
intersection(nums3, nums4); // [9, 4]
複製代碼
提示:輸出結果中的每一個元素是惟一的,能夠不考慮輸出結果的順序。
解題:
function intersection(arr1, arr2){
if(!Array.isArray(arr1) || !Array.isArray(arr2)) return []
let create = function(arr){
let sets = new Sets()
arr.map(item => sets.add(item))
return sets
}
let Sets1 = create(arr1)
let Sets2 = create(arr2)
let result = Sets1.intersection(Sets2)
return result.values()
}
複製代碼
使用示例以下:
const nums = [1, 2, 3];
subsets(nums);
// 輸出如下結果:
[
[3],
[1],
[2],
[1, 2, 3],
[1, 3],
[2, 3],
[1, 2],
[]
]
複製代碼
解題:
目前網絡上的最優解:
function subsets(nums){
if(!nums || !Array.isArray(nums)) return []
function diff (num, vec) {
let tmp = vec.slice(0)
result.push(tmp)
for (let i = num; i < len; i++) {
vec.push(nums[i])
diff(i + 1, vec)
vec.splice(-1)
}
}
const len = nums.length
let arr = [], result = []
diff(0, arr)
return result
}
複製代碼
窮舉法:
function subsets(nums){
if(!nums || !Array.isArray(nums)) return []
let result = [[]],
len = nums.length
if(len === 0) return result
for(let i = 0; i < len; i++){
let l = result.length
let num = nums[i]
let array = [num]
for(let j = 0; j < l; j++){
let tmparray = result[j].concat(array)
result.push(tmparray)
}
}
return result
}
複製代碼
下週將練習Dictionary 和 HashTable 的題目。