Java简单算法问题

常用排序方法:

1、冒泡排序:效率低,实现简单

/**

* 冒泡排序

* 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

* 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

* 针对所有的元素重复以上的步骤,除了最后一个。

* 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

* @param numbers 需要排序的整型数组

*/

public static void bubbleSort(int[] a) {
    int temp;
    int size = a.length;
    for(int i=1; i<size; i++) {
        for(int j=0; j<size-i; j++) {
            if(a[j] < a[j+1]) {
                temp = a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
}
View Code

2、选择排序:效率低,容易实现

/**

* 选择排序

* 在未排序序列中找到最小元素,存放到排序序列的起始位置

* 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列起始位置。

* 以此类推,直到所有元素均排序完毕。

* @param numbers

*/ 

public static void selectSort(int[] numbers) {   
    int size = numbers.length;
   int temp;   
    for (int i = 0; i < size; i++) {   
        int k = i;   
        for (int j = size - 1; j >i; j--)  {   
            if (numbers[j] < numbers[k]) {
      k = j;   
    }
        }   
        temp = numbers[i];   
        numbers[i] = numbers[k];   
        numbers[k] = temp;   
    }   
}
selectSort Code

3插入排序:效率低,容易实现

/**

* 插入排序

* 从第一个元素开始,该元素可以认为已经被排序

* 取出下一个元素,在已经排序的元素序列中从后向前扫描

* 如果该元素(已排序)大于新元素,将该元素移到下一位置

* 重复步骤3直到找到已排序的元素小于或者等于新元素的位置

* 将新元素插入到该位置中

* 重复步骤2

* @param numbers

*/ 

public static void insertSort(int[] numbers) {   
    int size = numbers.length, temp, j;   
    for(int i=1; i<size; i++) {   
        temp = numbers[i];   
        for(j = i; j > 0 && temp < numbers[j-1]; j--)   
            numbers[j] = numbers[j-1];   
        numbers[j] = temp;   
    }   
}
insertSort Code

4快速排序

/**

* 快速排序

* 从数列中挑出一个元素,称为基准

* 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,

* 该基准是它的最后位置。这个称为分割(partition操作。

* 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。

* @param numbers

* @param start

* @param end

*/

public void quickSort(int array[], int low, int high) {
// 传入low=0,high=array.length-1;
    int pivot, p_pos, i, t;// pivot->位索引;p_pos->轴值。
    if (low < high) {
        p_pos = low;
        pivot = array[p_pos];
        for (i = low + 1; i <= high; i++)
            if (array[i] > pivot) {
                p_pos++;
                t = array[p_pos];
                array[p_pos] = array[i];
                array[i] = t;
            }
        t = array[low];
        array[low] = array[p_pos];
        array[p_pos] = t;
        // 分而治之
        quickSort(array, low, p_pos - 1);// 排序左半部分
        quickSort(array, p_pos + 1, high);// 排序右半部分
    }
}
quickSort Code

简单算法问题汇总:

原文:http://www.cnblogs.com/gxbk629/p/3587562.html

1、兔子问题:递归

程序分析:兔子的规律为数列1,1,2,3,5,8,13,21....

public static int f(int x)
{
    if(x==1 || x==2)
        return 1;
    else
        return f(x-1)+f(x-2);
}
View Code

2101-200之间的素数

判断素数的方法:用一个数分别去除2sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数

public boolean iszhishu(int x)
{
    for(int i=2;i<=x/2;i++)
        if (x % i==0 )
            return false;
    return true;
}
View Code

3、水仙花数:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。

程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。

public boolean shuixianhua(int x)
{
   int i=0,j=0,k=0;
   i=x / 100;
   j=(x % 100) /10;
   k=x % 10;
   if(x==i*i*i+j*j*j+k*k*k)
      return true;
   else
      return false;
}
View Code

4、分解质因数:输入90,打印出90=2*3*3*5

程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:

(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。

(2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数,重复执行第一步。

(3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。

public void fengjie(int n){
    for(int i=2;i<=n/2;i++){
        if(n%i==0){
        System.out.print(i+"*");
        fengjie(n/i);
        }
    }
    System.out.print(n);
    System.exit(0);//不能少这句,否则结果会出错
}
View Code

5、输入两个正整数mn,求其最大公约数和最小公倍数

程序分析:利用辗除法 最小公倍数:m*n/最大公约数

public int gcd(int m, int n)    //最大公约数
{
    while (true)
    {
    if ((m = m % n) == 0)
    return n;
    if ((n = n % m) == 0)
    return m;
    }
}
View Code

6、完数:6=123.编程 找出1000以内的所有完数。

int s;
for(int i=1;i<=1000;i++)
{
 s=0;
 for(int j=1;j<i;j++)
     if(i % j==0)
         s=s+j;
    if(s==i)
        System.out.print(i+" ");
}
View Code

7、有1234个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

int i = 0;
int j = 0;
int k = 0;
String t = "";
int count = 0;
for(i=1;i<=4;i++){
    for(j=1;j<=4;j++){
        for(k=1;k<=4;k++){
            if(i!=j && j!=k && i!=k){
                t = "" + i + j + k;
                count++;
                System.out.println (t);
            }
        }
    }
    System.out.println(count);
}
View Code

8、一个整数,它加上100后是一个完全平方数,加上168又是一个完全平方数,请问该数是多少?

程序分析:在10万以内判断,先将该数加上100后再开方,再将该数加上268后再开方,如果开方后的结果满足如下条件,即是结果。

long k=0;
for(k=1;k<=100000l;k++)
    if(Math.floor(Math.sqrt(k+100))==Math.sqrt(k+100) && Math.floor(Math.sqrt(k+168))==Math.sqrt(k+168))
        System.out.println(k);
}
View Code

9、输入某年某月某日,判断这一天是这一年的第几天?

if(year%400==0||(year%4==0&&year%100!=0))/*判断是不是闰年*/ 
    leap=1;  
else 
    leap=0;
View Code

10、猴子吃桃:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。

程序分析:采取逆向思维的方法,从后往前推断。

public int total(int day){
    if(day == 10){
        return 1;
    }
    else{
        return (total(day+1)+1)*2;
    }
}
View Code

11、2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。

程序分析:请抓住分子与分母的变化规律。

float fm = 1f;
float fz = 1f;
float temp;
float sum = 0f;
for (int i=0;i<20;i++){
    temp = fm;
    fm = fz;
    fz = fz + temp;
    sum += fz/fm;
    //System.out.println(sum);
}
System.out.println(sum);
//请将上面数值计算全部换成BigDecimal计算,个人懒得弄,上述会出现精度丢失
View Code

12、求1+2!+3!+...+20!的和

static long sum = 0;
static long fac = 0;
public static void main(String[] args) {
    long sum = 0;
    long fac = 1;
    for(int i=1; i<=10; i++) {
        fac = fac * i;
        sum += fac;
    }
    System.out.println(sum);
}
//这是空间复杂度O(1),时间复杂度O(n)的方式,很慢,可以优化,请自行摸索
View Code

13、利用递归方法求5!

public long recursion(int n) {
    long value = 0 ;
    if(n ==1 || n == 0) {
        value = 1;
    } else if(n > 1) {
        value = n * recursion(n-1);
    }
    return value;
}
View Code

14、杨辉三角:

int i,j;
int a[][];
a=new int[8][8];
for(i=0;i<8;i++){
    a[i][i]=1;
    a[i][0]=1;
}
for(i=2;i<8;i++){
    for(j=1;j<=i-1;j++){
        a[i][j]=a[i-1][j-1]+a[i-1][j];
    }
} 
for(i=0;i<8;i++){
    for(j=0;j<i;j++){ 
        System.out.printf("  "+a[i][j]);
    }
    System.out.println();
}
View Code

15、幸运数字:约瑟夫环

/*

* 获取幸运数字

* 1,返回值类型int

* 2,参数列表int num

*/

public static int getLucklyNum(int num) {
    ArrayList<Integer> list = new ArrayList<>();   //创建集合存储1到num的对象
    for(int i = 1; i <= num; i++) {
        list.add(i);  //将1到num存储在集合中
    }
    int count = 1;                 //用来数数的,只要是3的倍数就杀人
    for(int i = 0; list.size() != 1; i++) {      //只要集合中人数超过1,就要不断的杀
        if(i == list.size()) {           //如果i增长到集合最大的索引+1时
            i = 0;                 //重新归零
        }
        if(count % 3 == 0) {           //如果是3的倍数
            list.remove(i--);             //就杀人
        }
        count++;
    }
    return list.get(0);
}

 

posted @ 2020-08-02 23:50  (1+0.01)²º²º  阅读(137)  评论(0)    收藏  举报