今天leetcode每日大卡做题题目中是卡牌问题,就是比如给你一个原始数组,例如[0,0,0,1,1,1,2,2,2],返回的就是 [0,0,0] [1,1,1] [2,2,2]
我思路:计算每个数字出现的次数,求其中的最大的公约数
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class GCD {
/**
* 求最大公约数 辗转相除法(欧几里德算法) 例如,求(319,377): ∵ 319÷377=0(余319)
* ∴(319,377)=(377,319); ∵ 377÷319=1(余58) ∴(377,319)=(319,58); ∵
* 319÷58=5(余29) ∴ (319,58)=(58,29); ∵ 58÷29=2(余0) ∴ (58,29)= 29; ∴
* (319,377)=29。 可以写成右边的格式。
* 用辗转相除法求几个数的最大公约数,可以先求出其中任意两个数的最大公约数,再求这个最大公约数与第三个数的最大公约数,依次求下去,直到最后一个数为止。
* 最后所得的那个最大公约数,就是所有这些数的最大公约数。
*
* @param m
* @param n
* @return
*/
public static int GCD(int m, int n) {
int result = 0;
while (n != 0) {
result = m % n;
m = n;
n = result;
}
return m;
}
/**
* 质因数分解法:把每个数分别分解质因数,再把各数中的全部公有质因数提取出来连乘,所得的积就是这几个数的最大公约数。 (小学学的方法)
*
* @param m
* @param n
* @return
*/
public static int PrimeGCD(int m, int n) {
int result = 1;
Set<Integer> set1 = getFactor(m);
Set<Integer> set2 = getFactor(n);
// 取交集
set1.retainAll(set2);
// 取最大
result = Collections.max(set1);
return result;
}
/**
* 更相减损术”,即“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。”
* @param m
* @param n
* @return
*/
public static int equalGCD(int m, int n) {
while (m != n) {
if (m > n)
m -= n;
else
n -= m;
}
return m;
}
/**
* 获取某一数值的所有因数
*
* @param m
* @return
*/
private static Set<Integer> getFactor(int m) {
Set<Integer> set = new HashSet<Integer>();
for (int i = 2; i <= m; i++) {
if (m % i == 0) {
set.add(i);
}
}
return set;
}
public static void main(String[] args) {
// int result = GCD(32, 48);
// int result = PrimeGCD(32, 48);
int result = equalGCD(32, 48);
System.out.println(result);
}
}
求质数:
import java.util.Scanner;
import java.util.TreeSet;
/**
* @author lmshe
* @create 2018-07-19 16:20
* @desc
*/
public class Test {
public static void main(String[] args) {
Scanner sca = new Scanner(System.in);
long num = sca.nextLong();
primeNumber(num);
//checkNumber(num);
}
/**
* 100-25,1000-168,10000-1229,100000-9592,1000000-78498,10000000-664579
* 获取输入数字以下所有素数
*/
public static void primeNumber(long num) {
long start = System.currentTimeMillis();
TreeSet<Integer> primeNumber = new TreeSet<>();
if (num < 10) {
//小于等于10,不做处理
} else {
//加入10以下素数
primeNumber.add(2);
primeNumber.add(3);
primeNumber.add(5);
primeNumber.add(7);
//大于2后,只需要判断奇数是否是素数即可
for (int i = 2; (2 * i - 1) <= num; i++) {
int curentNum = 2 * i - 1;
//过滤尾数为5的数字
if ((curentNum % 10) == 5) {
continue;
}
//过滤能被3整除的数字
if (count(curentNum) % 3 == 0) {
continue;
}
//求平方根,素数判断规则:除1和本身之外,没有其他约数,
//一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n)
//故只需要判断该数除以小于其平方跟以下的数,是否有整除即可区分是否是素数
int sq = (int) Math.sqrt(curentNum);
for (int k = 3; k <= sq; k++) {
if (curentNum % k == 0) {
break;
}
//判断是否是素数,能除到该值平方根的绝对值,且余数不为0,肯定是素数
if (curentNum % k != 0 && k == sq) {
primeNumber.add(curentNum);
}
}
}
}
//System.out.println("素数:" + primeNumber);
System.out.println(num + "以内共有" + primeNumber.size() + "个素数");
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
}
/**
* 判断输入数字是否是素数
*/
public static boolean checkNumber(long num) {
long start = System.currentTimeMillis();
boolean isPrime = true;
if (num < 10) {
//小于等于10,不做处理
} else {
//过滤尾数为5的数字
if ((num % 10) == 5) {
isPrime = false;
}
//过滤能被3整除的数字
else if (count(num) % 3 == 0) {
isPrime = false;
} else {
//求平方根,素数判断规则:除1和本身之外,没有其他约数,
//一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n)
//故只需要判断该数除以小于其平方跟以下的数,是否有整除即可区分是否是素数
int sq = (int) Math.sqrt(num);
for (int k = 3; k <= sq; k++) {
if (num % k == 0) {
isPrime = false;
break;
}
}
}
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start));
System.out.println("是否是素数:" + isPrime);
return isPrime;
}
//位数之和
public static int count(long num) {
int sum = 0;
while (num != 0) {
sum += num % 10;
num /= 10;
}
return sum;
}
}
leetcode 914
class Solution {
public boolean hasGroupsSizeX(int[] deck) {
// 计数
int[] counter = new int[10000];
for (int num: deck) {
counter[num]++;
}
// 求gcd
int x = 0;
for(int cnt: counter) {
if (cnt > 0) {
x = gcd(x, cnt);
if (x == 1) {
return false;
}
}
}
return x >= 2;
}
public static int gcd(int m, int n) {
int result = 0;
while (n != 0) {
result = m % n;
m = n;
n = result;
}
return m;
}
}