好的,所以我想知道如何检查两个数字是否具有相同的数字,例如21
和12
也可以,1233
和2313
,但123
和1233
不是,这意味着数字是另一个的排列数字的数字。
我知道如何使用数组或字符串或映射,但问题是,我不想用其中任何一个来做,如果存在另一个解决方案
阵列/地图的解决方案:
Map<int, int> counter = new HashMap<int, int>();
for (int i = 0; i < 10; i++)
counter.put(i, 0);
int x = 2421, y = 4223; // testcase
while (x > 0 || y > 0) {
if (x == 0 || y == 0) // if they are not the same length, one will be 0 and thus they are not permutations
return false;
counter.put(x%10, counter.get(x%10) + 1);
counter.put(y%10, counter.get(y%10) - 1);
x /= 10;
y /= 10;
}
// For each digit we added 1 to the counter if it was found in `x`
// and subtract 1 if it was found in `y`.
return counter.values() == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
现在,数组方法完全相同,因为使用数字0-9
的映射与使用map的键作为数组中的索引相同。没有任何数据结构的解决方案对我来说远非理想:
private static boolean haveSameDigits(int x, int y) {
// Because we are not allowed to use maps, declare 10 vars...
int c0 = 0;
int c1 = 0;
int c2 = 0;
int c3 = 0;
int c4 = 0;
int c5 = 0;
int c6 = 0;
int c7 = 0;
int c8 = 0;
int c9 = 0;
while (x > 0 || y > 0) {
if (x == 0 || y == 0)
return false;
if ((x % 10) == 0)
c0++;
else if ((x % 10) == 1)
c1++;
else if ((x % 10) == 2)
c2++;
else if ((x % 10) == 3)
c3++;
else if ((x % 10) == 4)
c4++;
else if ((x % 10) == 5)
c5++;
else if ((x % 10) == 6)
c6++;
else if ((x % 10) == 7)
c7++;
else if ((x % 10) == 8)
c8++;
else if ((x % 10) == 9)
c9++;
if ((y % 10) == 0)
c0--;
else if ((y % 10) == 1)
c1--;
else if ((y % 10) == 2)
c2--;
else if ((y % 10) == 3)
c3--;
else if ((y % 10) == 4)
c4--;
else if ((y % 10) == 5)
c5--;
else if ((y % 10) == 6)
c6--;
else if ((y % 10) == 7)
c7--;
else if ((y % 10) == 8)
c8--;
else if ((y % 10) == 9)
c9--;
x /= 10;
y /= 10;
}
return c0 == 0 && c1 == 0 && c2 == 0 && c3 == 0 && c4 == 0 && c5 == 0 && c6 == 0 && c7 == 0 && c8 == 0 && c9 == 0
}
我已经开始搜索它,但无论我输入什么,我最终得到了使用字符串或数组的解决方案。
我不是在寻找解决方案,我实际上并不想要它,我只需要提示这个方法。
添加更多信息:没有什么禁止我使用我想要的任何数据结构,这是我的程序,没有人会检查我做了什么。我就是那种喜欢学习新东西的人,所以我想知道是否有快速解决方案。
如评论中所述,可以迭代这两个数字并检查范围(0,9)中的每个数字,包括它们出现在字符串中的次数,但这显然会产生O(n*n)
的时间复杂度,这是Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
node._testadd()
TypeError: _testadd() missing 1 required positional argument: 'self'
不是最佳的。
答案 0 :(得分:2)
您不希望转换为字符串,也不想使用任何帮助程序数据结构。那怎么样:从数字中创建一个哈希,格式为xor(2^d for every digit d in n)
?
例如,hash(3112)
将是(二进制)1100
。
由于你不想要一个解决方案,这里有一些伪代码(又名Python):
def hash(n):
r = 0
while n > 0:
d = n % 10 # last digit
n = n // 10 # remaining digits
r = r ^ 2**d # xor with 2^d
return r
def perm(n, m):
return hash(n) == hash(m)
更新:结果证明上述情况不正常,因为XOR只能跟踪数字是偶数还是奇数次。相反,您可以使用多个素数创建哈希。这样,hash(3112)
变为7 * 3 * 3 * 5
。虽然这使用列表来保留前十个素数,但在检查单个数字对时不会创建任何新列表,数组或映射。另外,请记住,生成的哈希值可能非常大 - 大于Java的int
或long
类型。 (你可以采用另一个大素数的模数,但我不确定那个部分。)
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
def hash(n):
r = 1
while n > 0:
d = n % 10 # last digit
n = n // 10 # remaining digits
r = r * primes[d]
return r
答案 1 :(得分:0)
您可以将int解析为字符串并使用.contains
进行检查final List<Integer> intsForCheck = new ArrayList<>();
for (int i = 1; i < 180; i++)
intsForCheck.add(i);
final int num = 17;
intsForCheck.forEach(integer -> check(integer,num));
public static void check(int integer,int num)
{
final String _int = String.valueOf(integer);
final String _num = String.valueOf(num);
System.out.println(_int + (_int.contains(_num) ? " contains" : " not contains") + _num);
}