(1)阶乘
1,给定一个数N,则N!的末尾有多少零?
分析:
10=2*5; N!=2^x * 5^y * …;
0的个数M=min(x,y); 2出现的频率比5出现的频率大的多,故M=y;
即题目可化为求 1-N中5的指数
int count=0;
for(int i=1;i<=N;i++){
int j=i;
while(j%5==0){
count++;
j=j/5;
}
}
2,求N! 的二进制表示中最低位1的位置.
分析:
二进制数右移一位,即相当于除以2
左移一位,相当于乘以2
即问题等同于 求N!含有质因数2的个数+1.
而N!中含有质因数2的个数,等于(N-N的二进制表示中含1的个数)故,
int count=0;
while(N!=0){
N=N&(N-1);
count++;
}
int result=N-count+1;
3,一个整数N,判断N是否为2的方幂
(N>0)&&(N&(N-1)==0)
3,找到出现次数超过总数一半的数,
分析:
先排序,然后取a[N/2]即可。
4,给定一个十进制正整数N,计算从1-N的所有整数中出现“1”的个数。
分析:
遍历1-N中所有的数,将每个数中含有“1”的个数,叠加。
int sum=0;
for(int i=1;i<=N;i++){
sum+=count1Num(i);
}
private int count1Num(int i){
int count=0;
while(i!=0){
if(i%10==1){
count++;
}
i=i/10;
}
return i;
}
输出7有关数字的个数,包括7的倍数,还有包含7的数字(如17,27,37…70,71,72,73…)的个数
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int count=0;
for(int i=0;i<n;i++){
if(i%7==0){
count++;
}
int num=i;
while(num>0){
int tmp=num%10;
if(tmp==7)
count++;
num=num/10;
}
}
5,寻找N个数中最大的K个数
快速排序 NlogN:快排的每一步,都是将待排的数据分为两组,其中一组数据的任何一个数都比另一组中任一个数大,再对两组分别做类似的操作,。。继续下去..
选择排序:选择N个数中的前K个数
二分查找 mid=min+(max-min)/2;
6,辗转相除法求最大公约数,
f(x,y)=f(y,x%y) (x>=y>0)
f(42,30)=f(30,12)=f(12,6)=f(6,0)=6
求最大公约数
public int getcd(int x,int y){
if(y!=0){
return getcd(y,x%y);
}else
return x;
}
解法二,由于取余复杂度较高,
因为f(x,y)=f(x-y,y)
f(42,30)=f(30,12)=f(18,12)=f(12,6)=f(6,0)=6;
private BigInt gcd(BigInt x,BigInt y){
if(x<y)
return gcd(y,x);
if(y==0)
return x;
else
return gcd(x-y,y);
}
7,斐波那契数列Fibonacci
private int Fibonacci(int n){
if(n<=0)
return 0;
else if(n==1)
return 1;
else
return Fibonacci(n-1)+Fibonacci(n-2);
}
8,给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…A[i-1]*A[i+1]…*A[n-1]。不能使用除法。
import java.util.ArrayList;
public class Solution {
public int[] multiply(int[] A) {
int len=A.length;
int[] b=new int[A.length];
if(A.length==0)
return b;
int[] c=new int[len];
int[] d=new int[len];
c[0]=A[0];
d[len-1]=A[len-1];
for(int i=1;i<len;i++){
c[i]=c[i-1]*A[i];
}
for(int i=len-2;i>=0;i--){
d[i]=d[i+1]*A[i];
}
b[0]=d[1];
b[len-1]=c[len-2];
for(int i=1;i<len-1;i++){
b[i]=c[i-1]*d[i+1];
}
return b;
}
}
9,求数组中的子数组之和的最大值
import java.util.*;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
List<Integer> list=new ArrayList<Integer>();
if(array.length==0||array==null)
return 0;
for(int i=0;i<array.length;i++){
int sum=0;
for(int j=i;j<array.length;j++){
sum+=array[j];
list.add(sum);
}
}
Collections.sort(list);
return list.get(list.size()-1);
}
}
10,数数出列— 约瑟夫环
输入字符串长度,字符串,计数m。从前往后计数,当数到m个元素时,m个元素出列,同时将该元素赋值给m,然后从下一个数计数循环,直到所有数字都出列,给定的数全部为大于0的数字。输出出队队列。
例如: 输入:len=4 str=”3,1,2,4” m=7
输出:2,3,1,4
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
while(sc.hasNextLine()){
int len=Integer.parseInt(sc.nextLine());
String s=sc.nextLine();
int M=Integer.parseInt(sc.nextLine());
for(int i=0;i<s.length();i++){
if(s.charAt(i)<=0){
System.out.println("error");
}
}
int index=0;
List<Integer> nums=new ArrayList<Integer>();
List<Integer> out=new ArrayList<Integer>();
String[] ss=s.split(",");
for(int i=0;i<ss.length;i++){
nums.add(Integer.parseInt(ss[i]));
}
while(nums.size()>0){
int m=M%nums.size();
while(m>1){
index++;
if(index==nums.size())
index=0;
m--;
}
int del=nums.remove(index);
out.add(del);
if(index==nums.size())
index=0;
M=del;
}
System.out.println(out);
}
sc.close();
}
}
11,2Sum
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
public int[] twoSum(int[] nums,int target){
int[] a=new int[2];
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
map.put(nums[i],i);
}
for(int i=0;i<nums.length;i++){
int gap=target-nums[i];
if(map.get(gap)!=null&&map.get(gap)!=i){
a[0]=i+1;
a[1]=map.get(gap)+1;
break;
}
}
return a;
}
12,3Sum
eg: given array s={-1,0,1,2,-1,-4},
A solution set is:
{-1,0,1},{-1,-1,2}
public class Solution{
ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();
public ArrayList<ArrayList<Integer>> threeSum(int[] nums){
if(nums==null||nums.length<3)
return list;
Arrays.sort(nums);
int len =nums.length;
for(int i=0;i<len-2;i++){
if(i>0&&nums[i]==nums[i-1])
continue;
find(nums,i+1,len-1,nums[i]);
}
return list;
}
public void find(int[] nums,int begin,int end,int target){
int l=begin,r=end;
while(l<r) {
if(nums[l]+nums[r]+target==0){
List<Integer> ans=new ArrayList<>();
ans.add(target);
ans.add(nums[l]);
ans.add(nums[r]);
list.add(ans);
while(l<r&&nums[l]==nums[l+1])l++;
while(l<r&&nums[r]==nums[r-1])r--;
l++;
r--;
}else if(nums[l]+nums[r]+target<0)
l++;
else
r--;
}
}
}
13, Minimum Path Sum
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
public int minPathSum(int[][] grid){
return dfs(0,0,grid);
}
public int dfs(int i,int j,int [][] grid){
if(i==grid.length-1&&j==grid[0].length-1){
return grid[i][j];
}
if(i<grid.length-1&&j<grid[0].length-1){
int r1=grid[i][j]+dfs(i+1,j,grid);
int r2=grid[i][j]+dfs(i,j+1,grid);
return Math.min(r1,r2);
}
if(i<grid.length-1)
return grid[i][j]+dfs(i+1,j,grid);
if(j<grid[0].length-1)
return grid[i][j]+dfs(i,j+1,grid);
return 0;
}
14,求数组中最长递增子序列
int[] d=new int[array.length];
int max=0;
for(int i=0;i<array.length;i++){
d[i]=1;
for(int j=0;j<i;j++){
if(a[i]>a[j]&&d[i]<d[j]+1)
d[i]=d[j]+1;
if(max<d[i])
max=d[i];
}
}
return max;
15,数组分割
有一元素个数为2n的整数数组,如何把这个数组分为元素个数为n的子数组,且使两个子数组的和最接近?
分析:
排序,然后化为奇数项数组和偶数项数组s1和s2
接着,从s1和s2中找出一对数进行交换,是sum(s1)和sum(s2)相差最小。