算法-java(1)

(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的数字(如17273770717273…)的个数
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)相差最小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值