数学类知识
一、数学技巧解题
数组
1、求众数
如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为n/2
的元素(下标从 0 开始)一定是众数。
public static int majorityElement(int[] nums){
Arrays.sort(nums);
int n = nums.length;
return nums[n/2];
}
2、二维递增数组找target
从左下角开始搜寻。
public static boolean searchMatrix(int[][] matrix, int target){
int rows = matrix.length;
int cols = matrix[0].length;
int row = rows-1, col = 0;
while (row >= 0 && col < cols){
if(matrix[row][col] > target)
row--;
else if(matrix[row][col] < target)
col++;
else if(matrix[row][col] == target)
return true;
}
return false;
}
3、求素数
public static int countPrime(int n){
boolean[] isPrime = new boolean[n];
Arrays.fill(isPrime, true);
for (int i = 0; i < n; i++) {
if(isPrime[i]){
for (int j = i*i; j < n; j += i) {
isPrime[j] = false;
}
}
}
int count = 0;
for (int i = 2; i < n; i++) {
if(isPrime[i]) count++;
}
return count;
}
求丑数
public static int nthUglyNumber(int n){
int a = 0, b = 0, c = 0;
int[] dp = new int[n];
dp[0] = 1;
for (int i = 1; i < n; i++) {
int n2 = dp[a] * 2, n3 =dp[b] * 3, n5 = dp[c] * 5;
dp[i] = Math.min(Math.min(n2, n3), n5);
if(dp[i] == n2) a++;
if(dp[i] == n3) b++;
if(dp[i] == n5) c++;
}
return dp[n-1];
}
字符串
二、实现数学运算
1、概率
2、平方、开方
3、阶乘
4、整除、mod
4、幂次
三、实现数学几何运算
数组
1、合法三角形
public static int trianglenumber(int[] nums){
int n = nums.length;
Arrays.sort(nums);
int ret = 0;
int left, right;
for (int i = 0; i < n; ++i) {
right = i + 2;
for (int j = i + 1; j < n; ++j) {
left = j + 1;
while(right < n && nums[right] < nums[i] + nums[j]) right++;
ret += Math.max(right - left, 0);
}
}
return ret;
}
2、实现字符串+,-的简单计数器
public static int sampleCounter(String s){
Deque<Integer> ops = new LinkedList<Integer>();
ops.push(1);
int sign = 1;
int ret = 0;
int n = s.length();
int i = 0;
while (i < n) {
if (s.charAt(i) == ' ') {
i++;
} else if (s.charAt(i) == '+') {
sign = ops.peek();
i++;
} else if (s.charAt(i) == '-') {
sign = -ops.peek();
i++;
} else if (s.charAt(i) == '(') {
ops.push(sign);
i++;
} else if (s.charAt(i) == ')') {
ops.pop();
i++;
} else {
long num = 0;
while (i < n && Character.isDigit(s.charAt(i))) {
num = num * 10 + s.charAt(i) - '0';
i++;
}
ret += sign * num;
}
}
return ret;
}
3、n个骰子的点数之和的概率
public static double[] dicesProbability(int n) {
double[] dp = new double[6];
Arrays.fill(dp, 1.0 / 6.0);
for (int i = 2; i <= n; i++) {
double[] tmp = new double[5 * i + 1];
for (int j = 0; j < dp.length; j++) {
for (int k = 0; k < 6; k++) {
tmp[j + k] += dp[j] / 6.0;
}
}
dp = tmp;
}
return dp;
}
四、经典数学类问题
1、 斐波那契数列
2、汉诺塔问题
public static void hanota(List<Integer> A, List<Integer> B, List<Integer> C) {
int n = A.size();
hanoi(n,A,B,C);
}
public static void hanoi(int n, List<Integer> A, List<Integer> B, List<Integer> C) {
if (n == 1){
C.add(A.remove(A.size()-1));
return;
}
else {
hanoi(n - 1, A, C, B);
C.add(A.remove(A.size()-1));
hanoi(n - 1, B, A, C);
}
}
3、逆波兰表达式求值
public static int evalRPN(String[] tokens){
Stack<Integer> stack = new Stack<>();
int n = tokens.length;
for (int i = 0; i < n; i++) {
if(!isNUmber(tokens[i])){
stack.push(Integer.parseInt(tokens[i]));
}
else{
stack.add(count(stack.pop(), stack.pop(), tokens[i]));
}
}
return stack.peek();
}
public static int count(int b, int a, String sign){
if(sign.equals("+"))
return a+b;
else if(sign.equals("-"))
return a-b;
else if(sign.equals("*"))
return a*b;
else
return a/b;
}
private static boolean isNUmber(String token) {
return (token.equals("+")||token.equals("-")||token.equals("/")||token.equals("*"));
}
4、约瑟夫环
public static int josephus(int[] nums, int countNum, int startNO) {
// 初始化人数
List<Integer> start = new ArrayList<Integer>();
int n = nums.length;
for (int i = 1; i <= n; i++) {
start.add(i);
}
int k = startNO - 1;
while (start.size() > 1) {
k = (k + countNum) % (start.size()) - 1;
if (k < 0) {
start.remove(start.size() - 1);
k = 0;
} else {
start.remove(k);
}
}
return start.get(0);
}