统计所有小于非负整数 n 的质数的数量。
示例:
输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
算法思想:以10为例子,首先排除1,因为1既不是质数也不是合数。
从2开始,以一个Boolean数组(默认为false)标记数字,false和true
[false false false false false false false false ]
[2 3 4 5 6 7 8 9 ]
[2 true true true ]
可以看出,如果2是质数,2的倍数4,6,8一定不是质数
同理,3是质数,3的倍数,3,6,9一定不是质数
class Solution {
public int countPrimes(int n) {
if(n <=1) return 0;
int count = 0;
//初始化一个Boolean数组,标记每一个数字是true还是false;
boolean isPrime[] = new boolean[n+1];
for(int i =2; i<n; i++){
if(isPrime[i] == false){
count++;
}
for(int j = i+i; j<n; j+= i){
isPrime[j] = true;
}
}
return count;
}
}
//最大公约数
public static int gcb(int a, int b){
//辗转相除法
//例如,求(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。
return b == 0? a : gcb(b, a%b);
}
//最小公倍数= a*b*最大公约数
public static int lcm(int a ,int b){
return a * b* gcb(a,b);
}
给定一个整数,将其转化为7进制,并以字符串形式输出。
示例 1:
输入: 100
输出: “202”
示例 2:
输入: -7
输出: “-10”
class Solution {
public String convertToBase7(int num) {
//以字符串形式输出
StringBuffer buffer = new StringBuffer();
int str = 0;
boolean flag = false;
if(num < 0){
num = -1*num;
flag = true;
}
while(num >= 7){
str = num % 7;
num = num/ 7;
buffer.append(str);
}
buffer.append(num);
String res = new String(buffer.reverse());
if(flag){
return "-" + res;
}
return res;
}
}
在Java中0x开头表示十六进制,如0xf= 15(10)
0开头表示八进制,比如012 = 10(10)
没有前缀才代表十进制数字
0X100000000LL 表示的是一个十六进制的长长整型数
转换为10进制就是4294967296 也就是2的32次方
nums & 0xf 表示只取低四位
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1 和 0。
示例 1:
输入: a = “11”, b = “1”
输出: “100”
示例 2:
输入: a = “1010”, b = “1011”
输出: “10101”
class Solution {
public String addBinary(String a, String b) {
int i = a.length()-1;
int j = b.length()-1;
int carry = 0;
StringBuilder res = new StringBuilder();
while(i>=0 && j >= 0){
int sum = a.charAt(i) - '0'+ b.charAt(j)-'0'+carry;
carry = sum/2;//进位值
sum = sum % 2; //留下来的低位值
res.append(sum);
i--;
j--;
}
//a还剩余值
while(i>=0){
int sum = a.charAt(i) - '0'+carry;
carry = sum/2;//进位值
sum = sum % 2; //留下来的低位值
res.append(sum);
i--;
}
//b还剩余值
while(j >= 0){
int sum = b.charAt(j)-'0'+carry;
carry = sum/2;//进位值
sum = sum % 2; //留下来的低位值
res.append(sum);
j--;
}
//处理进位
if(carry > 0){
res.append(carry);
}
return res.reverse().toString();
}
}
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。
注意:
num1 和num2 的长度都小于 5100.
num1 和num2 都只包含数字 0-9.
num1 和num2 都不包含任何前导零。
你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。
class Solution {
public String addStrings(String num1, String num2) {
//十进制加法
int i = num1.length()-1;
int j = num2.length()-1;
StringBuilder res= new StringBuilder();
int carry =0;
while(i >= 0 && j>=0){
int sum = num1.charAt(i) -'0'+num2.charAt(j)-'0'+carry;
carry = sum / 10;
sum = sum % 10;
res.append(sum);
i--;
j--;
}
while(i >= 0 ){
int sum = num1.charAt(i) -'0'+carry;
carry = sum / 10;
sum = sum % 10;
res.append(sum);
i--;
}
while(j>=0){
int sum = num2.charAt(j)-'0'+carry;
carry = sum / 10;
sum = sum % 10;
res.append(sum);
j--;
}
if(carry>0){
res.append(carry);
}
return res.reverse().toString();
}
}
给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。
例如:
输入:
[1,2,3]
输出:
2
说明:
只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1):
[1,2,3] => [2,2,3] => [2,2,2]
class Solution {
public int minMoves2(int[] nums) {
//a和b都移动到m位置上,总共需要(a-m)+(m-b)=(a-b);
//计算a-b就好
Arrays.sort(nums);
int a = 0;
int move =0;
int b = nums.length-1;
while(a<=b){
move += nums[b] - nums[a];
b--;
a++;
}
return move;
}
}
给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。
说明:不要使用任何内置的库函数,如 sqrt。
示例 1:
输入:16
输出:True
示例 2:
输入:14
输出:False
class Solution {
public boolean isPerfectSquare(int num) {
//平方序列是1,4,9,16,25,36,49
//间隔位:3,5,7,9,11,13
//可以看出平方序列的间隔序列是一个间隔为2的等差数列
int subNum = 1;
while(num > 0){
num -= subNum;
subNum += 2;
}
return num==0;
}
}
给定一个整数,写一个函数来判断它是否是 3 的幂次方。
示例 1:
输入: 27
输出: true
示例 2:
输入: 0
输出: false
示例 3:
输入: 9
输出: true
class Solution {
public boolean isPowerOfThree(int n) {
if(n<1) return false;
while(n %3 == 0){
n /= 3;
}
return n==1;
}
}