Skip to content

Commit 2635ec2

Browse files
committed
数学
公倍公约 多数投票 相遇 素数 字符串加减 进制转换 其他
1 parent b79b831 commit 2635ec2

14 files changed

+507
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package 数学.公约公倍;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/11.
5+
* 最大公约数
6+
7+
int gcd(int a, int b) {
8+
return b == 0 ? a : gcd(b, a% b);
9+
}
10+
最小公倍数为两数的乘积除以最大公约数。
11+
12+
int lcm(int a, int b){
13+
return a * b / gcd(a, b);
14+
}
15+
对于最大公约数问题,因为需要计算 a % b ,而这个操作是比较耗时的,可以使用 编程之美:2.7 的方法,利用减法和移位操作来替换它。
16+
17+
对于 a 和 b 的最大公约数 f(a, b),有:
18+
19+
如果 a 和 b 均为偶数,f(a, b) = 2*f(a/2, b/2);
20+
如果 a 是偶数 b 是奇数,f(a, b) = f(a/2, b);
21+
如果 b 是偶数 a 是奇数,f(a, b) = f(a, b/2);
22+
如果 a 和 b 均为奇数,f(a, b) = f(a, a-b);
23+
乘 2 和除 2 都可以转换为移位操作。
24+
*/
25+
public class 最大公约数和最小公倍数 {
26+
27+
}

src/数学/其他/乘积数组.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package 数学.其他;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Created by 周杰伦 on 2018/4/12.
7+
*/
8+
public class 乘积数组 {
9+
public static void main(String[] args) {
10+
int []a = {1,2,3,4};
11+
System.out.println(Arrays.toString(productExceptSelf(a)));
12+
}
13+
14+
// 不用除法
15+
// public int[] productExceptSelf(int[] nums) {
16+
// int n = nums.length;
17+
// int[] ret = new int[n];
18+
// ret[0] = 1;
19+
// int left = 1;
20+
// for (int i = 1; i < n; i++) {
21+
// ret[i] = left * nums[i - 1];
22+
// left *= nums[i - 1];
23+
// }
24+
// int right = 1;
25+
// for (int i = n - 1; i >= 0; i--) {
26+
// ret[i] *= right;
27+
// right *= nums[i];
28+
// }
29+
// return ret;
30+
// }
31+
32+
//用了除法
33+
public static int[] productExceptSelf(int[] nums) {
34+
if (nums.length <= 1)return nums;
35+
int all = 1;
36+
int cnt = 0;
37+
int index = 0;
38+
for (int i = 0; i < nums.length;i ++) {
39+
if (nums[i] != 0) {
40+
all *= nums[i];
41+
}else {
42+
cnt ++;
43+
if (cnt == 2) {
44+
break;
45+
}
46+
index = i;
47+
}
48+
}
49+
if (cnt == 2) {
50+
Arrays.fill(nums, 0);
51+
return nums;
52+
}else {
53+
if (index != 0) {
54+
Arrays.fill(nums, 0);
55+
nums[index] = all;
56+
return nums;
57+
}else {
58+
for (int i = 0;i < nums.length;i ++) {
59+
nums[i] = all / nums[i];
60+
}
61+
return nums;
62+
}
63+
}
64+
}
65+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package 数学.其他;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/12.
5+
*/
6+
public class 判断一个数是否是3的n次方 {
7+
public static void main(String[] args) {
8+
System.out.println(isPowerOfThree(45));
9+
}
10+
// //1162261467是32位系统中,3的最高次幂19
11+
public static boolean isPowerOfThree(int n) {
12+
return n > 0 && (1162261467 % n == 0);
13+
}
14+
}

src/数学/其他/平方数.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package 数学.其他;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/12.
5+
*/
6+
public class 平方数 {
7+
8+
// 平方序列:1,4,9,16,.. 间隔:3,5,7,...
9+
//
10+
// 间隔为等差数列,使用这个特性可以得到从 1 开始的平方序列。
11+
//
12+
// public boolean isPerfectSquare(int num) {
13+
// int subNum = 1;
14+
// while (num > 0) {
15+
// num -= subNum;
16+
// subNum += 2;
17+
// }
18+
// return num == 0;
19+
// }
20+
21+
public boolean isPerfectSquare(int num) {
22+
if (num == 1 || num == 0)return true;
23+
for (int i = 2;i <= num / 2;i ++) {
24+
if (i * i == num) {
25+
return true;
26+
}
27+
}
28+
return false;
29+
}
30+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package 数学.其他;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Created by 周杰伦 on 2018/4/12.
7+
*/
8+
public class 找出数组中的乘积最大的三个数 {
9+
public static void main(String[] args) {
10+
int []a = {1,2,3,4};
11+
System.out.println(maximumProduct(a));
12+
}
13+
public static int maximumProduct(int[] nums) {
14+
if(nums.length < 3) return 0;
15+
if(nums.length == 3) return nums[0] * nums[1] * nums[2];
16+
Arrays.sort(nums);
17+
int max = Integer.MIN_VALUE;
18+
if ( nums[0] < 0 && nums[1] < 0) {
19+
max = nums[0] * nums[1] * nums[nums.length - 1];
20+
}
21+
if (nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3] > max) {
22+
max = nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3];
23+
}
24+
return max;
25+
}
26+
27+
// public int maximumProduct(int[] nums) {
28+
// int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE, min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
29+
// for (int n : nums) {
30+
// if (n > max1) {
31+
// max3 = max2;
32+
// max2 = max1;
33+
// max1 = n;
34+
// } else if (n > max2) {
35+
// max3 = max2;
36+
// max2 = n;
37+
// } else if (n > max3) {
38+
// max3 = n;
39+
// }
40+
//
41+
// if (n < min1) {
42+
// min2 = min1;
43+
// min1 = n;
44+
// } else if (n < min2) {
45+
// min2 = n;
46+
// }
47+
// }
48+
// return Math.max(max1*max2*max3, max1*min1*min2);
49+
// }
50+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package 数学.多数投票问题;
2+
3+
import java.util.HashMap;
4+
import java.util.Set;
5+
6+
/**
7+
* Created by 周杰伦 on 2018/4/12.
8+
*/
9+
public class 数组中出现次数多于二分之一n的的元素 {
10+
public static void main(String[] args) {
11+
int []a = {1,3,2,2,76,2,43,2,56,1,2,2,3,3,3,12,2,2,2,2,2,2,2,};
12+
System.out.println(majorityElement(a));
13+
}
14+
public static int majorityElement(int[] nums) {
15+
if (nums.length == 0)return 0;
16+
if (nums.length == 1)return nums[0];
17+
if (nums.length == 2)return nums[0];
18+
HashMap<Integer, Integer> map = new HashMap<>();
19+
int n = nums.length;
20+
for (int i = 0; i < nums.length; i++) {
21+
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
22+
}
23+
Set<Integer> set = map.keySet();
24+
for (int i : set) {
25+
if (map.get(i) > n/2) {
26+
return i;
27+
}
28+
}
29+
return 0;
30+
}
31+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package 数学.字符串加法减法;
2+
3+
import com.sun.org.apache.xerces.internal.impl.dv.xs.Base64BinaryDV;
4+
5+
/**
6+
* Created by 周杰伦 on 2018/4/12.
7+
*/
8+
public class 二进制加法 {
9+
public String addBinary(String a, String b) {
10+
int carry = 0;
11+
int i = a.length() - 1;
12+
int j = b.length() - 1;
13+
StringBuilder sb = new StringBuilder();
14+
while (carry == 1|| i >= 0 || j >= 0) {
15+
if (i >= 0 && a.charAt(i --) == '1')carry ++;
16+
if (j >= 0 && b.charAt(j --) == '1')carry ++;
17+
sb.append(carry % 2);
18+
carry /= 2;
19+
}
20+
return sb.reverse().toString();
21+
}
22+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package 数学.字符串加法减法;
2+
3+
/**
4+
* Created by 周杰伦 on 2018/4/12.
5+
*/
6+
public class 字符串加法 {
7+
public static void main(String[] args) {
8+
String a ="123";
9+
String b = "442";
10+
System.out.println(addStrings(a, b));
11+
}
12+
public static String addStrings(String num1, String num2) {
13+
int carry = 0;
14+
int i = num1.length() - 1;
15+
int j = num2.length() - 1;
16+
StringBuilder sb = new StringBuilder();
17+
while (carry == 1|| i >= 0 || j >= 0) {
18+
int x = i < 0 ? 0 : num1.charAt(i --) - '0';
19+
int y = j < 0 ? 0 : num2.charAt(j --) - '0';
20+
sb.append((x + y + carry) % 10);
21+
carry = (x + y + carry) / 10;
22+
}
23+
return sb.reverse().toString();
24+
}
25+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package 数学.相遇问题;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Created by 周杰伦 on 2018/4/12.每次可以对一个数组元素加一或者减一,求最小的改变次数。
7+
8+
这是个典型的相遇问题,移动距离最小的方式是所有元素都移动到中位数。理由如下:
9+
10+
设 m 为中位数。a 和 b 是 m 两边的两个元素,且 b > a。要使 a 和 b 相等,它们总共移动的次数为 b - a,这个值等于 (b - m) + (m - a),也就是把这两个数移动到中位数的移动次数。
11+
12+
设数组长度为 N,则可以找到 N/2 对 a 和 b 的组合,使它们都移动到 m 的位置。
13+
*/
14+
public class 改变数组元素使所有的数组元素都相等 {
15+
public static void main(String[] args) {
16+
int []a = {1,2,3};
17+
System.out.println(minMoves2(a));
18+
}
19+
//
20+
public static int minMoves2(int[] nums) {
21+
if (nums.length == 0)return 0;
22+
long []cost = new long[nums.length];
23+
long min = Integer.MAX_VALUE;
24+
for (int i = 0; i < nums.length; i++) {
25+
for (int j = 0; j < nums.length; j++) {
26+
if (i != j) {
27+
cost[i] += Math.abs(nums[j] - nums[i]);
28+
}
29+
}
30+
if (cost[i] < min) {
31+
min = cost[i];
32+
}
33+
}
34+
return (int) min;
35+
}
36+
//先排序,时间复杂度:O(NlogN)
37+
// public int minMoves2(int[] nums) {
38+
// Arrays.sort(nums);
39+
// int ret = 0;
40+
// int l = 0, h = nums.length - 1;
41+
// while(l <= h) {
42+
// ret += nums[h] - nums[l];
43+
// l++;
44+
// h--;
45+
// }
46+
// return ret;
47+
// }
48+
49+
// 解法 2
50+
51+
// 使用快速选择找到中位数,时间复杂度 O(N)
52+
//
53+
// public int minMoves2(int[] nums) {
54+
// int ret = 0;
55+
// int n = nums.length;
56+
// int median = quickSelect(nums, 0, n - 1, n / 2 + 1);
57+
// for(int num : nums) ret += Math.abs(num - median);
58+
// return ret;
59+
// }
60+
//
61+
// private int quickSelect(int[] nums, int start, int end, int k) {
62+
// int l = start, r = end, privot = nums[(l + r) / 2];
63+
// while(l <= r) {
64+
// while(nums[l] < privot) l++;
65+
// while(nums[r] > privot) r--;
66+
// if(l >= r) break;
67+
// swap(nums, l, r);
68+
// l++; r--;
69+
// }
70+
// int left = l - start + 1;
71+
// if(left > k) return quickSelect(nums, start, l - 1, k);
72+
// if(left == k && l == r) return nums[l];
73+
// int right = r - start + 1;
74+
// return quickSelect(nums, r + 1, end, k - right);
75+
// }
76+
//
77+
// private void swap(int[] nums, int i, int j) {
78+
// int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp;
79+
// }
80+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package 数学.素数;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Created by 周杰伦 on 2018/4/5.
7+
* 素数
8+
9+
素数分解
10+
11+
每一个数都可以分解成素数的乘积,例如 84 = 22 * 31 * 50 * 71 * 110 * 130 * 170 * …
12+
13+
整除
14+
15+
令 x = 2m0 * 3m1 * 5m2 * 7m3 * 11m4 * … 令 y = 2n0 * 3n1 * 5n2 * 7n3 * 11n4 * …
16+
17+
如果 x 整除 y(y mod x == 0),则对于所有 i,mi <= ni。
18+
19+
x 和 y 的 最大公约数 为:gcd(x,y) = 2min(m0,n0) * 3min(m1,n1) * 5min(m2,n2) * ...
20+
21+
x 和 y 的 最小公倍数 为:lcm(x,y) = 2max(m0,n0) * 3max(m1,n1) * 5max(m2,n2) * ...
22+
*/
23+
public class 生成素数序列 {
24+
public static void main(String[] args) {
25+
26+
System.out.println(countPrimes(10));
27+
}
28+
public static int countPrimes(int n) {
29+
boolean []prime = new boolean[n];
30+
Arrays.fill(prime, true);
31+
int count = 0;
32+
for (int i = 2;i < n;i ++) {
33+
if (prime[i] == true) {
34+
count ++;
35+
}
36+
for (int j = 2;i * j < n;j ++) {
37+
prime[i * j] = false;
38+
}
39+
}
40+
return count;
41+
}
42+
43+
}

0 commit comments

Comments
 (0)