Algorithm 如何检查数字是否为彩色数字?

Algorithm 如何检查数字是否为彩色数字?,algorithm,Algorithm,彩色数字: 一个数字可以分成不同的子序列部分。假设一个数字3245可以被分解成像3 2 4 5 32 24 45 324 245这样的部分。这个数字是一个彩色的数字,因为子序列中每个数字的乘积都是不同的。也就是说,32445(3*2)=6(2*4)=8(4*5)=20(3*2*4)=24(2*4*5)=40 但是326不是一个彩色数字,因为它生成326(3*2)=6(2*6)=12 您必须编写一个函数来判断给定的数字是否是彩色数字。一个简单的解决方案是枚举所有产品并将其记录在哈希映射中 在双循环

彩色数字:

一个数字可以分成不同的子序列部分。假设一个数字3245可以被分解成像
3 2 4 5 32 24 45 324 245
这样的部分。这个数字是一个彩色的数字,因为子序列中每个数字的乘积都是不同的。也就是说,
32445(3*2)=6(2*4)=8(4*5)=20(3*2*4)=24(2*4*5)=40

但是
326
不是一个彩色数字,因为它生成
326(3*2)=6(2*6)=12


您必须编写一个函数来判断给定的数字是否是彩色数字。

一个简单的解决方案是枚举所有产品并将其记录在哈希映射中

在双循环中枚举所有产品:

  • 通过增加启动指数

  • 然后通过增加结束索引,每次乘以当前数字

    3,3.2,3.2.4,3.2.4.5;2, 2.4, 2.4.5; 4, 4.5; 5

您可以验证这是否生成所有产品。(它还生成完整序列的产物,但这是无害的,因为它不会创建额外的解决方案。)

在最坏的情况下,即数字是彩色的,如果假设哈希映射插入和查找是固定时间操作,则这将需要大约O(N²)的时间。

我已经有了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");
}
解决包装问题;
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.lang.Exception;
导入java.lang.Integer;
导入java.lang.String;
导入java.lang.System;
导入java.util.HashSet;
导入java.util.Set;
/**
*彩色数字:
*一个数字可以分成不同的子序列部分。
*假设一个数字3245可以分解成3 2 4 5 32 24 45 324 245这样的部分。
*这个数字是彩色的,因为每个数字的乘积
*子序列是不同的。
*也就是说,32445(3*2)=6(2*4)=8(4*5)=20(3*2*4)=24(2*4*5)=40
*但326并不是一个彩色数字,因为它生成了326(3*2)=6(2*6)=12。
*/
公共类彩色数{
公共静态void main(字符串[]args)引发异常{
String numString=new BufferedReader(new InputStreamReader(System.in)).readLine();
int num=Integer.parseInt(numString);
int length=numString.length();
int[]位数=新的int[长度];
int索引=长度-1;
Set productSet=new HashSet();
while(num>0){
数字[索引]=num%10;
if(productSet.contains(数字[索引])
{
System.out.println(“不是彩色数字”);
返回;
}否则{
//System.out.println(“在“+索引”处添加“+数字[索引]+”);
productSet.add(数字[索引]);
}
num=num/10;
索引--;
}
对于(int x=1;x对于(int i=0;i请检查此项。如果我遗漏了任何测试用例,请告诉我

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;
}
public int彩色(int a){
字符串s=String.valueOf(a);
Set=newhashset();
内部温度=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;

}
public int彩色(int A){
HashSet HashSet=新的HashSet();
ArrayList编号=新的ArrayList();
while(A!=0){
int num=A%10;
数字。添加(num);
A/=10;
}
收藏。反面(数字);
int n=numbers.size();
对于(int i=0;i
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;
  }

}
类解决方案{
公共int彩色(INTA){
HashSet map=新的HashSet();
char[]num=String.valueOf(A).toCharArray();
如果(数值长度>10)
返回0;
int product[][]=新int[num.length][num.length];

对于(int i=0;i这是动态规划解决方案。我们开始填补空白,直到我们看到一个产品已经看到。如果我们没有看到任何产品重复,直到最后一位数字,数字是彩色的

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;
    }

}
import java.util.HashSet;
导入java.util.Set;
导入java.util.Stack;
/**
*彩色数字:在给定的数字中,子序列中每个数字的乘积都是不同的。该数字称为彩色数字。参见示例
*例如:
*指定号码:3245
*输出:彩色
*数字3245可以分解为3 2 4 5 32 24 45 324 245这样的部分。
*这个数字是一个彩色的数字,因为子序列中每个数字的乘积都是不同的。
*也就是说,32445(3*2)=6(2*4)=8(4*5)=20,(3*2*4)=24(2*4*5)=40
*指定号码:326
*输出:不彩色。
*326不是一个彩色数字,因为它生成了326(3*2)=6(2*6)=12。
*资源:https://algorithms.tutorialhorizon.com/colorful-numbers/
*/
公共类彩色数字{
公共静态void main(字符串[]args){
ColorfulNumbers ColorfulNumbers=新的ColorfulNumbers();
整数=3245;
System.out.println(colorfolnumbers.isColorful(number));
数字=326;
System.out.println(colorfolnumbers.isColorful(number));
}
/**
*动态规划解决方案,用于查看数字是否彩色。第0列保留原始数字。
*产品[i][j]是指从索引i到索引j的数字的乘积。产品[i][j]等于产品[i][j-1]
*乘法数字[j]。
*
*@param number输入编号
*@return数字是否彩色
*/
公共布尔isColorful(i)
'''
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