彩色数字:
一个数字可以分成不同的子序列部分。假设,数字3245可以分为3 2 4 5 32 24 45 324 245
等部分。并且该数字是彩色数字,因为子序列的每个数字的乘积是不同的。也就是3 2 4 5 (3*2)=6 (2*4)=8 (4*5)=20 (3*2*4)= 24 (2*4*5)= 40
但326
生成3 2 6 (3*2)=6 (2*6)=12
时不是彩色数字。
您必须编写一个函数,告诉您给定的数字是否为彩色数字。
答案 0 :(得分:4)
一个简单的解决方案是枚举所有产品并将其记录在哈希映射中。
您在双循环中枚举所有产品:
通过增加起始指数;
然后通过增加结束指数,每次乘以当前数字。
3, 3.2, 3.2.4, 3.2.4.5; 2, 2.4, 2.4.5; 4, 4.5; 5
您可以验证这会生成所有产品。 (它还生成完整序列的产品,但这是无害的,因为它不会创建额外的解决方案。)
在最坏的情况下,即数字是彩色的,如果你假设哈希映射插入和查找是恒定时间操作,这将花费大约O(N²)时间。
答案 1 :(得分:1)
我已经解决了这个问题的O(n²)问题。任何人都有更好的解决方案。
package ProblemSolving;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.Exception;
import java.lang.Integer;
import java.lang.String;
import java.lang.System;
import java.util.HashSet;
import java.util.Set;
/**
* Colorful Number:
* A number can be broken into different sub-sequence parts.
* Suppose, a number 3245 can be broken into parts like 3 2 4 5 32 24 45 324 245.
* And this number is a colorful number, since product of every digit of a
* sub-sequence are different.
* That is, 3 2 4 5 (3*2)=6 (2*4)=8 (4*5)=20 (3*2*4)= 24 (2*4*5)= 40
* But 326 is not a colorful number as it generates 3 2 6 (3*2)=6 (2*6)=12.
*/
public class ColorfulNumber {
public static void main(String[] args) throws Exception {
String numString = new BufferedReader(new InputStreamReader(System.in)).readLine();
int num = Integer.parseInt(numString);
int length = numString.length();
int[] digits = new int[length];
int index = length - 1;
Set<Integer> productSet = new HashSet<Integer>();
while (num > 0) {
digits[index] = num % 10;
if(productSet.contains(digits[index]))
{
System.out.println("Not a colorful number");
return;
}else{
//System.out.println("Added "+digits[index]+" at "+index);
productSet.add(digits[index]);
}
num = num / 10;
index--;
}
for (int x = 1; x < length; x++) {
int product = 1;
for(int i=0;i<x;i++)
{
product = product*digits[i];
}
for (int y = x; y < length; y++) {
if(productSet.contains( product * digits[y]))
{
System.out.println("Not a colorful number");
//System.out.println("Not a colorful number "+ product * digits[y]+" exists");
return;
}else{
//System.out.println("Added "+ product * digits[y]);
productSet.add( product * digits[y]);
}
}
}
System.out.println("Colorful number");
}
}
答案 2 :(得分:1)
请检查一下。如果我错过了任何测试用例,请告诉我。
public int colorful(int a) {
String s = String.valueOf(a);
Set<Integer> set = new HashSet<>();
int temp = 0;
while (temp < s.length()) {
//If consecutive Integer is same return 0
if (set.contains(s.charAt(temp) - '0')) return 0;
set.add(s.charAt(temp) - '0');
temp++;
}
int i = 0;
int j = 1;
int n = s.length();
int val1 = 0;
int val2 = 0;
while (j < n) {
val1 = s.charAt(i) - '0';
val2 = s.charAt(j) - '0';
if (set.contains(val1*val2))
return 0;
set.add(val1 * val2);
i++;
j++;
}
return 1;
}
答案 3 :(得分:0)
您需要以下代码
public int colorful(int A) {
HashSet<Integer> hashSet = new HashSet<>();
ArrayList<Integer> numbers = new ArrayList<>();
while (A != 0) {
int num = A % 10;
numbers.add(num);
A /= 10;
}
Collections.reverse(numbers);
int n = numbers.size();
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int prod = 1;
for (int k = i; k <= j; k++) {
prod = prod * numbers.get(k);
}
if (hashSet.contains(prod))
return 0;
hashSet.add(prod);
}
}
return 1;
}
答案 4 :(得分:0)
你去了。 :D
class Solution {
public int colorful(int A) {
HashSet<Integer> map = new HashSet<>();
char[] num = String.valueOf(A).toCharArray();
if(num.length>10)
return 0;
int product[][] = new int[num.length][num.length];
for(int i=0; i<num.length; i++){
for(int j=i; j<num.length; j++){
if(i==j){
product[i][i] = num[i]-'0';
}
else product[i][j] = product[i][j-1]*(num[j]-'0');
if(map.contains(product[i][j]))
return 0;
else map.add(product[i][j]);
}
}
return 1;
}
}
答案 5 :(得分:0)
这是动态编程解决方案。我们开始填补空白,直到我们看到一种产品已经出现。如果直到最后一位都看不到任何重复的产品,则该数字是彩色的。
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
/**
* Colorful Number: When in a given number, product of every digit of a sub-sequence are different. That number is called Colorful Number. See Example
* Example:
* Given Number : 3245
* Output : Colorful
* Number 3245 can be broken into parts like 3 2 4 5 32 24 45 324 245.
* this number is a colorful number, since product of every digit of a sub-sequence are different.
* That is, 3 2 4 5 (3*2)=6 (2*4)=8 (4*5)=20, (3*2*4)= 24 (2*4*5)= 40
* Given Number : 326
* Output : Not Colorful.
* 326 is not a colorful number as it generates 3 2 6 (3*2)=6 (2*6)=12.
* Resource: https://algorithms.tutorialhorizon.com/colorful-numbers/
*/
public class ColorfulNumbers {
public static void main(String[] args) {
ColorfulNumbers colorfulNumbers = new ColorfulNumbers();
int number = 3245;
System.out.println(colorfulNumbers.isColorful(number));
number = 326;
System.out.println(colorfulNumbers.isColorful(number));
}
/**
* A dynamic programming solution to see if a number is colorful or not. Column 0 keeps the original digits.
* products[i][j] means the product of the digits from index i to index j. Products[i][j] equals products[i][j-1]
* multiply digit[j].
*
* @param number The input number
* @return Whether the number is colorful or not
*/
public boolean isColorful(int number) {
Set<Integer> seenProducts = new HashSet<>();
int[] digits = getDigits(number);
int n = digits.length;
int[][] products = new int[n][n];
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
if (j == 0) {
int currentDigit = digits[i];
if (seenProducts.contains(currentDigit)) {
return false;
} else {
seenProducts.add(currentDigit);
products[i][j] = currentDigit;
}
} else {
if (i < j) {
int previousProduct = i == j - 1 ? products[i][0] : products[i][j - 1];
int currentProduct = previousProduct * products[j][0];
if (seenProducts.contains(currentProduct)) {
return false;
} else {
seenProducts.add(currentProduct);
products[i][j] = currentProduct;
}
}
}
}
}
return true;
}
/**
* Returns the digits of a number as an array.
*
* @param number The number
* @return The digits of the number
*/
private int[] getDigits(int number) {
Stack<Integer> digitsStack = new Stack<>();
while (number > 0) {
int remainder = number % 10;
digitsStack.push(remainder);
number = number / 10;
}
int n = digitsStack.size();
int[] digits = new int[n];
for (int i = 0; i < n; i++) {
digits[i] = digitsStack.pop();
}
return digits;
}
}
我希望这会有所帮助。
答案 6 :(得分:0)
我知道这篇文章发布已经有一段时间了,但这仍然是一个反复出现的编码挑战,所以我想我会用 Python 贡献我的解决方案。
我的解决方案将数字分解为一个字符列表(len = 1 的字符串),然后使用滑动窗口来获取子序列。获得单个子序列后,将其整数乘积添加到字典中。如果在任何时候字典已经有某个键,则返回 False。否则,如果所有 subseq 产品都是唯一的,则返回 True。
'''
colorful uses a sliding window to get all subsequences. Then, it will check subseq. products against a dictionary to see if they've already been added. If so,
then return False. If all of the subseq products are unique, then function returns True.
The sliding window idea will add keys to the dictionary like the following.
Note: Insertion order in dictionaries is maintained in Python 3.7+
Input: 3245
1) list(check.keys()) = [3]
2) list(check.keys()) = [3, 6]
3) list(check.keys()) = [3, 6, 24]
4) list(check.keys()) = [3, 6, 24, 2]
5) list(check.keys()) = [3, 6, 24, 2, 8]
6) list(check.keys()) = [3, 6, 24, 2, 8, 40]
7) list(check.keys()) = [3, 6, 24, 2, 8, 40, 4]
8) list(check.keys()) = [3, 6, 24, 2, 8, 40, 4, 20]
9) list(check.keys()) = [3, 6, 24, 2, 8, 40, 4, 20, 5]
'''
def colorful(A):
# break integer down into an array of numeric strings representing each digit
# ex: an input of 3245 will create arr = ['3', '2', '4', '5']
arr = list(str(A))
check = {}
# If arr is 1 unit long, then it's trivially true
if len(arr) == 1:
return True
else: # case where arr is bigger than 2 units long
win_left = 0
win_right = 1
while win_left <= (len(arr) - 1): # Prevents left side of window from going out of bounds
# Making sure right side of window is only every at most 1 unit outside of arr to the right AND make sure that the window doesn't cover the whole arr
# because, we don't want the original number itself. We just want the subsequences.
while (win_right <= len(arr)) and (win_right - win_left < len(arr)):
prod = 1
for char in arr[win_left:win_right]: # The splice here is why we are okay with the right side of window being outside of array. Splices are exclusive
prod *= int(char)
if prod in check:
return False
else:
check[prod] = 1 # add subseq prod to check dictionary and put a default value. We don't care about value.
win_right += 1
win_left += 1
win_right = win_left + 1
return True