使用 hashmap

问题描述

所以我在 codewar 上遇到了编码问题。指令去 “给定两个数组 a 和 b,编写一个函数 comp(a,b) (orcompSame(a,b)) 来检查这两个数组是否具有“相同”的元素,具有相同的多重性。“相同”在这里的意思是b 中的元素是 a 平方中的元素,无论顺序如何。

示例 有效数组 a = [121,144,19,161,11]
b = [121,14641,20736,361,25921,361] comp(a,b) 返回真,因为在 b 中,121 是 11 的平方,14641 是 121 的平方,20736 是 144 的平方,361 是 19 的平方,25921 是 161 的平方,依此类推。如果我们用平方来写 b 的元素就很明显了:

a = [121,11] b = [1111,121121,144144,1919,161161,1919] 无效数组 例如,如果我们将第一个数字更改为其他数字,comp 可能不再返回 true:

a = [121,11]
b = [132,b) 返回 false,因为在 b 中 132 不是任意数 a 的平方。

a = [121,36100,b) 返回 false,因为在 b 中 36100 不是任意数 a 的平方。

备注 a 或 b 可能是 [](除 R、Shell 之外的所有语言)。 a 或 b 可能是 nil 或 null 或 None 或什么都没有(C++、Elixir、Haskell、PureScript、Pascal、R、Rust、Shell 除外)。 如果 a 或 b 为 nil(或 null 或 None),则问题没有意义,因此返回 false。”

这是我的解决方

import java.util.HashMap;

公开课主{

public static int BiggestElement(int [] arr) {
    int result = 0;
    result = arr[0];
    for(int i=0;i<arr.length;i++) {
        if(arr[i]>= result) {
            result = arr[i];
        }
    }
    
    return result;
}

public static boolean comp(int[] a,int []b) {
    int size = a.length;
    if(a.length != b.length) {
        System.out.println("They don't have the same size");
        return false;
    }
    else {
        //First we need to check which one has the biggest element
        int biggestA = 0;
        int biggestB = 0;
        System.out.println(biggestA = BiggestElement(a));
        System.out.println(biggestB = BiggestElement(b));
        
        //creating two maps 
        HashMap<Integer,Integer> map1 = new HashMap<Integer,Integer>();
        HashMap<Integer,Integer> map2 = new HashMap<Integer,Integer>();
        //Now we put every value of b inside the map
        for(int i = 0; i<a.length;i++) {
            map1.put(a[i],i);
            map2.put(b[i],i);
        }
        
        //Now we do the actual comparision
        if(biggestA>biggestB) {
            for(int  i=0;i<size;i++) {
                if(!map1.containsKey(b[i]*b[i])) {
                    return false;
                }
            }
        } else {
            for(int  i=0;i<size;i++) {
                if(!map2.containsKey(a[i]*a[i])) {
                    System.out.println("map 1 doesn't contain " + (b[i]*b[i]));
                    return false;
                }
            }
        }
        
    }
    return true;
}

public static void main(String[] args) {
    int[] a = new int[]{121,11};
    int[] b = new int[]{121,361};
    
    System.out.println(comp(a,b));
}

}

我提交了我的代码,他们做了 13 次测试,但我失败了 3 次。任何人都向我提出了任何建议或解决方案,以便我改进。

解决方法

关于您上面的方法,您依靠映射键来跟踪数组值。但是,映射不能有重复的键,因此每当您为给定键向映射添加值时,旧值都会被替换。

因此以下数组将进行相等比较(它们不是 - 4s 中的 b 之一应该是 16

int[] a = {1,2,3,4,4}; 
int[] b = {1,9,16,4};

好吧,这是一种方法。我相当肯定还有其他可能更有效的方法。主要的一点是它记录每次值出现的次数,并将该次数用作比较过程的一部分。

  • 首先,检查以确保数组不为空,并且长度与任何例程可能会这样做的长度相同。
  • 然后找出哪个数组有正方形(虽然在调用方法之前应该知道这一点)。
  • 然后计算每个 n 方格出现的次数。
  • 然后对于每个值 n,从值计数中减去 1。
  • 如果该值变为负数,则立即返回 false,因为一对一映射不存在。
  • 否则,遍历这些值,如果有任何非零值,则返回 false。
public static boolean comp(int[] a,int[] b) {

    if (a == null || b == null ||
            (a.length != b.length)) {
                   return false;
    }

    int maxVal = Integer.MIN_VALUE;
    int maxSquare = Integer.MIN_VALUE;
    for(int i = 0; i < vals.length; i++) {
        maxVal = Math.max(vals[i],maxVal);
        maxSquare = Math.max(squares[i],maxSquare);
    }
    // swap them if required
    if (maxVal > maxSquare) {
        int[] temp = squares;
        squares = vals;
        vals = temp;
    }
    Map<Integer,Integer> mapA = new HashMap<>();
    for (int el : a) {
        mapA.compute(el * el,(k,v) -> v == null ? 1 : v + 1);
    }
    
    for (int el : b) {
        if (mapA.computeIfPresent(el,v) -> v - 1) < 0) {
            return false;
        }
    }
    
    for (int i : mapA.values()) {
        if (i != 0) {
            return false;
        }
    }
    return true;
    
}
,

代码如下:

public static boolean comp(int[] a,int []b) {
    if(a.length != b.length) {
        System.out.println("They don't have the same size");
        return false;
    }
    Set<Integer> set = new HashSet<Integer>();
    for(int i: a) {
        set.add(i);
        set.add(i * i);
    }
    for(int i: b)
    {
        if(!set.contains(i) && !set.contains(i * i))
            return false;
    }
    return true;
}