Javascript 两个数组的isSubset

Javascript 两个数组的isSubset,javascript,algorithm,Javascript,Algorithm,我想用几个测试用例得到两个数组的子集。我不想使用javascript,因为每个函数都太简单了。我的尝试是有效的,但我不认为它是时间和空间复杂性O(n^2)的最佳选择 我的测试用例如下: 1) array1的所有值都应在array2 2) 如果在array1中存在重复值,则在array2中也应考虑重复值。例如,如果arr1=[“a”,“a”]和arr2=[“b”,“a”]则isSubset为false,因为“a”在第一个中出现两次,但在第二个中仅出现一次 以下是我的解决方案: let arr1 =

我想用几个测试用例得到两个数组的子集。我不想使用javascript,因为每个函数都太简单了。我的尝试是有效的,但我不认为它是时间和空间复杂性O(n^2)的最佳选择

我的测试用例如下:

1)
array1
的所有值都应在
array2

2) 如果在
array1
中存在重复值,则在
array2
中也应考虑重复值。例如,如果
arr1=[“a”,“a”]
arr2=[“b”,“a”]
则isSubset为
false
,因为
“a”
在第一个中出现两次,但在第二个中仅出现一次

以下是我的解决方案:

let arr1 = ["A", "B", "C"];
let arr2 = ["C", "A", "B", "D"];

function isSubset(a, b) {
  if(a.length > b.length) {
    return false;
  }

  var myHash = {};
  for (var i = 0; i < a.length; ++i) {
    if(myHash[a[i]]) {
      myHash[a[i]] += 1;
    } else {
      myHash[a[i]] = 1;
    }
  }

  var myHash2 = {};
  for (var i = 0; i < b.length; ++i) {
    if(myHash2[b[i]]) {
      myHash2[b[i]] += 1;
    } else {
      myHash2[b[i]] = 1;
    }
  }


  for(var i in myHash) {
    for(var j in myHash2) {
      if(i == j && myHash[i] > myHash2[j]) {
        return false;
      }
    }
  }


  return true;
}

// test
var a = ["B", "A", "C", "A"];
var b = ["A", "B", "C", "D"];
var c = isSubset(a, b);
console.log(c);
让arr1=[“A”、“B”、“C”];
设arr2=[“C”,“A”,“B”,“D”];
功能发布集(a、b){
如果(a.长度>b.长度){
返回false;
}
var myHash={};
对于(变量i=0;imyHash2[j]){
返回false;
}
}
}
返回true;
}
//试验
变量a=[“B”、“a”、“C”、“a”];
变量b=[“A”、“b”、“C”、“D”];
var c=发行集(a,b);
控制台日志(c);

Codepen:

您不需要嵌套循环,因为您已经在
myHash2
中计算了计数。查一查。将嵌套循环替换为

for(var i in myHash) {
  if (myHash[i] > myHash2[i])
    return false;
}
时间复杂度为:O(n),其中n是较大数组的长度。如果仅当密钥存在时(如vivek_23所示),才从
myHash
中减去计数器,则还可以完全消除对
myHash2
的需要

这也可以在O(nlogn)+O(n)中完成,其中
n
是较大数组的长度,无需使用额外内存。O(n logn)表示排序。基本上,我们同时迭代两个数组,并在元素相等的情况下递增指针。如果
arr2
中的元素较大,则找不到元素,我们返回
false
。如果我们一直到达
arr1
的末尾,则会找到所有元素,并返回
true

function isSubset(arr1, arr2) {
  arr1 = arr1.sort();
  arr2 = arr2.sort();
  let idx1 = 0, idx2 = 0;
  while (idx1 < arr1.length) {
    if (idx2 >= arr2.length) {
      return false;
    }
    if (arr1[idx1] > arr2[idx2]) {
      idx2++;
    } else if (arr1[idx1] == arr2[idx2]) {
      idx1++; idx2++;
    } else {
      return false;
    }
  }
  return true;
}
功能问题集(arr1、arr2){
arr1=arr1.sort();
arr2=arr2.sort();
设idx1=0,idx2=0;
而(idx1=arr2.长度){
返回false;
}
if(arr1[idx1]>arr2[idx2]){
idx2++;
}else if(arr1[idx1]==arr2[idx2]){
idx1++;idx2++;
}否则{
返回false;
}
}
返回true;
}

您不需要嵌套循环,因为您已经在
myHash2
中计算了计数。查一查。将嵌套循环替换为

for(var i in myHash) {
  if (myHash[i] > myHash2[i])
    return false;
}
时间复杂度为:O(n),其中n是较大数组的长度。如果仅当密钥存在时(如vivek_23所示),才从
myHash
中减去计数器,则还可以完全消除对
myHash2
的需要

这也可以在O(nlogn)+O(n)中完成,其中
n
是较大数组的长度,无需使用额外内存。O(n logn)表示排序。基本上,我们同时迭代两个数组,并在元素相等的情况下递增指针。如果
arr2
中的元素较大,则找不到元素,我们返回
false
。如果我们一直到达
arr1
的末尾,则会找到所有元素,并返回
true

function isSubset(arr1, arr2) {
  arr1 = arr1.sort();
  arr2 = arr2.sort();
  let idx1 = 0, idx2 = 0;
  while (idx1 < arr1.length) {
    if (idx2 >= arr2.length) {
      return false;
    }
    if (arr1[idx1] > arr2[idx2]) {
      idx2++;
    } else if (arr1[idx1] == arr2[idx2]) {
      idx1++; idx2++;
    } else {
      return false;
    }
  }
  return true;
}
功能问题集(arr1、arr2){
arr1=arr1.sort();
arr2=arr2.sort();
设idx1=0,idx2=0;
而(idx1=arr2.长度){
返回false;
}
if(arr1[idx1]>arr2[idx2]){
idx2++;
}else if(arr1[idx1]==arr2[idx2]){
idx1++;idx2++;
}否则{
返回false;
}
}
返回true;
}
  • 你就快到了。创建一个散列对象,而不是创建两个不同的散列对象。第一个数组用于递增
    散列
    值,另一个数组用于递减存储在
    散列
    中的值

  • 现在,如果存储在
    散列中的计数大于零,则表示数组
    b
    中缺少某个值。否则,我们都有利于子集目标

功能发布集(a、b){
如果(a.长度>b.长度){
返回false;
}
var hash={};
对于(var i=0;i
  • 就快到了。不要创建两个不同的哈希对象,而是创建一个哈希对象。第一个数组用于递增
    哈希值,另一个数组用于递减
    哈希值中存储的值

  • 现在,如果
    散列
    中存储的计数大于零,则表示数组
    b
    中缺少某个值。否则,我们都适合子集目标

功能发布集(a、b){
如果(a.长度>b.长度){
返回false;
}
var hash={};

对于(var i=0;i您可以获取一个哈希表,并从第一个数组向上和从第二个数组向下对所有项进行计数。如果所有计数均为零,则两个数组共享同一集合

功能发布集(a、b){
函数计数(array,inc){
var i=数组长度;
而(i--)hash[array[i]=(hash[array[i]]| | 0)+inc;
}
var hash={},i,键;
计数(a,1);
计数(b,-1);
keys=Object.keys(散列);
i=键。长度;
而(i--)if(hash[keys[i]])返回false;
返回true;
}
log(isSubset([“B”、“A”、“C”、“A”],[“A”、“B”、“C”、“A”]);//true
log(isSubset([“B”、“A”、“C”、“A”]、[“A”、“B”、“C”、“D”]);//false
console.log(isSubset([“B”、“A”、“C”、“A”][