今日面试

1、冒泡排序

冒泡排序中,最重要的思想是两两比较,将两者较少的升上去
冒泡排序最坏情况的时间复杂度是O(n²)
 
代码:
[cpp] view plain copy
 
 print?
  1. #include <stdio.h>  
  2. void swap(int *a, int *b);  
  3. int main()  
  4. {  
  5.     int    array[10] = {15, 225, 34, 42, 52, 6, 7856, 865, 954, 10};  
  6.     int    i, j;  
  7.     for (i = 0; i < 10; i++)  
  8.     {  
  9.         //每一次由底至上地上升  
  10.         for (j = 9; j > i; j--)  
  11.         {  
  12.             if (array[j] < array[j-1])  
  13.             {  
  14.                     swap(&array[j], &array[j-1]);  
  15.             }  
  16.         }  
  17.     }  
  18.     for (i = 0; i < 10; i++)  
  19.     {  
  20.         printf("%d\n", array[i]);  
  21.     }  
  22.     return    0;  
  23. }  
  24. void swap(int *a, int *b)  
  25. {  
  26.     int    temp;  
  27.     temp = *a;  
  28.       *a = *b;  
  29.       *b = temp;  
  30. }  

冒泡排序算法只会将较少的逐步向上推,不会造成文章前面所说的不足,这里就不给予演示。
有些追求完美的人就会思考,冒泡排序能不能优化呢?
答案是能的。如何优化的文章在这里

 

 

 
首页 > 专题系列 > 算法分析 > 求两个有序数组的中位数-算法导论
2014
07-12

求两个有序数组的中位数-算法导论

 

Question

There are 2 sorted arrays A and B of size n each. Write an algorithm to find the median of the array obtained after merging the above 2 arrays(i.e. array of length 2n). The complexity should be O(log(n))。

有两个排序的数组,长度都为n,求合并后的排序数组的中位数。

题目是《算法导论》上的一道习题,不过已多次出现在面试题当中。注意,此题中两个数组的长度是相等的。当然,长度不等的话也可以做,只是要多些判断条件。参考leetcode题目 Median of Two Sorted Arrays

方法1 直接遍历

直接的解法是遍历两个数组并计数,类似归并排序里面的有序数组的合并,复杂度为O(n)。代码如下:

01 #include <iostream>
02 #include <stdio.h>
03 using namespace std;
04  
05 double getMedian(int arr1[],int arr2[], int n){
06     int i=0,j=0; //分别是 arr1, arr2的当前下标
07     int m1=-1,m2=-1; //保存两个中位数. 由于是2n个,肯定有两个中位数
08     for(int cnt=0; cnt<=n; cnt++){
09         if( i<n && (arr1[i] < arr2[j] || j >= n )){
10             m1 = m2;
11             m2 = arr1[i++];
12         }else{
13             m1 = m2;
14             m2 = arr2[j++];
15         }
16     }
17     return (m1+m2)/2.0;
18 }
19 int main()
20 {
21     int ar1[] = {1, 12, 15, 26, 38};
22     int ar2[] = {2, 13, 17, 30, 45};
23  
24     int n1 = sizeof(ar1)/sizeof(ar1[0]);
25     int n2 = sizeof(ar2)/sizeof(ar2[0]);
26     if (n1 == n2)
27         printf("Median is %lf", getMedian(ar1, ar2, n1));
28     else
29         printf("Doesn't work for arrays of unequal size");
30     return 0;
31 }

方法2 分治法

要求的复杂度为O(log (m+n)),很显然需要用分治法求解。

假设数组A的中位数为m1,数组B为m2,例如:

ar1[] = {1, 12, 15, 26, 38}
ar2[] = {2, 13, 17, 30, 45}

m1 = 15 ,m2 = 17 。由于m1<m2,则可以确定中位数即为下面两个子数组的中位数 :

[15, 26, 38]  和 [2, 13, 17]

重复这个步骤,可以得到   m1 = 26 m2 = 13. 得到两个子数组:

[15, 26] 和[13, 17]

这时,由于n=2,无法在继续分下去了。可以直接计算得:

1 median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2
2                       = (max(15, 13) + min(26, 17))/2
3                       = (15 + 17)/2
4                       = 16

代码如下:

01 int median(int arr[], int n)
02 {
03     if (n%2 == 0)
04         return (arr[n/2] + arr[n/2-1])/2;
05     else
06         return arr[n/2];
07 }
08  
09 int getMedian(int ar1[], int ar2[], int n) {
10     int m1;
11     int m2;
12     if (n <= 0)
13         return -1;
14     if (n == 1)
15         return (ar1[0] + ar2[0]) / 2;
16  
17     if (n == 2)
18         return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2;
19  
20     m1 = median(ar1, n);
21     m2 = median(ar2, n);
22     /* 相等可直接返回 */
23     if (m1 == m2)
24         return m1;
25     if (m1 < m2) {
26         if (n % 2 == 0)
27             return getMedian(ar1 + n/2-1, ar2, n/2 + 1);
28         else
29             return getMedian(ar1 + n/2, ar2, n/2+1);
30     else {
31         if (n % 2 == 0)
32             return getMedian(ar2 + n/2-1, ar1, n/2+1);
33         else
34             return getMedian(ar2 + n/2, ar1, n/2+1);
35     }
36 }
37  
38 int main()
39 {
40     int ar1[] = {1, 12, 10, 26, 38};
41     int ar2[] = {2, 13, 17, 30, 45};
42  
43     int n1 = sizeof(ar1)/sizeof(ar1[0]);
44     int n2 = sizeof(ar2)/sizeof(ar2[0]);
45     if (n1 == n2)
46         printf("Median is %d", getMedian(ar1, ar2, n1));
47     else
48         printf("Doesn't work for arrays of unequal size");
49     return 0;
50 }

 

时间复杂度为 O(logn)。

 
 
 
覆盖和重载的区别
override->重写(=覆盖)、overload->重载、polymorphism -> 多态
 
override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。
重写(覆盖)的规则:
   1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载.
   2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。
   3、重写的方法的返回值必须和被重写的方法的返回一致;
   4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;
   5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写。
   6、静态方法不能被重写为非静态的方法(会编译出错)。
 
overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。
重载的规则:
   1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样);
   2、不能通过访问权限、返回类型、抛出的异常进行重载;
   3、方法的异常类型和数目不会对重载造成影响;
 
多态的概念比较复杂,有多种意义的多态,一个有趣但不严谨的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法。
一般,我们使用多态是为了避免在父类里大量重载引起代码臃肿且难于维护。
 
 
 

Java中对Array数组的常用操作

 

目录:

  1. 声明数组;
  2. 初始化数组;
  3. 查看数组长度;
  4. 遍历数组;
  5. int数组转成string数组;
  6. 从array中创建arraylist;
  7. 数组中是否包含某一个值;
  8. 将数组转成set集合;
  9. 将数组转成list集合;
  10. Arrays.fill()填充数组;
  11. 数组排序;
  12. 复制数组;
  13. 比较两个数组;
  14. 去重复;
  15. 查询数组中的最大值和最小值;

备注:文内代码具有关联性。

1.声明数组;

1
2
3
4
String [] arr;
int arr1[];
String[] array=new String[5];
int score[]=new int[3];

 

2.初始化数组;

1
2
3
4
5
6
7
8
9
10
//静态初始化
int arr2[]=new int[]{1,2,3,4,5};
String[] array1={"马超","马云","关羽","刘备","张飞"};
String[] array2=new String[]{"黄渤","张艺兴","孙红雷","小猪","牙哥","黄磊"};
int score[]=new int[3];
//动态初始化
for(int i=0;i<score.length;i++)
{   
  score[i]=i+1
}

 

 

3.查看数组长度;

1
2
int length=array1.length;
System.out.println("length:  "+array1.length);

 

4.遍历数组;

1
2
3
for (int i = 0; i < array1.length; i++) {
    System.out.println(array1[i]);
}

 

5.int数组转成string数组;

1
2
3
int[]  array3={1,2,3,4,5,6,7,8,9,0};
        String arrStrings=Arrays.toString(array3);
        System.out.println(arrStrings);

 

 6.从array中创建arraylist;

1
2
ArrayList<String> arrayList=new ArrayList<String>(Arrays.asList(array1));
System.out.println(arrayList);

 

7.数组中是否包含某一个值;

1
2
3
4
5
String a="马超";
String[] array1={"马超","马云","关羽","刘备","张飞"};
if (Arrays.asList(array1).contains(a)) {
    System.out.println("马超在这里");
}

 

8.将数组转成set集合;

1
2
3
String[] array2=new String[]{"黄渤","张艺兴","孙红雷","小猪","牙哥","黄磊"};
    Set<String> set=new HashSet<String>(Arrays.asList(array2));
    System.out.println(set);

 

9.将数组转成list集合;

1
2
3
4
5
6
7
8
9
10
11
String[] array2=new String[]{"黄渤","张艺兴","孙红雷","小猪","牙哥","黄磊"};
//方法 1.
List<String> list=new ArrayList<String>();
for (int i = 0; i < array2.length; i++) {
    list.add(array2[i]);
}
 
String[] arrStrings2={"1","2","3"};
//方法 2.
List<String > list2=java.util.Arrays.asList(arrStrings2);
System.out.println(list2);

 

10.Arrays.fill()填充数组;

1
2
3
4
5
6
int[] arr3=new int[5];
        Arrays.fill(arr3, 10);  //将数组全部填充10
               //遍历输出
        for (int i = 0; i < arr3.length; i++) {
            System.out.println(arr3[i]);
        }

 

11.数组排序;

1
2
3
4
5
6
7
8
9
10
11
12
//方法 1.
int[] arr4 = {37219};
Arrays.sort(arr4);         //.sort(int[] a)   放入数组名字
for (int i = 0; i < arr4.length; i++) {
    System.out.println(arr4[i]);
}
//方法 2.        
int[] arr5 = {37219,3,45,7,8,8,3,2,65,34,5};
Arrays.sort(arr5, 14);  //.sort(a, fromIndex, toIndex)    从第几个到第几个之间的进行排序
for (int i = 0; i < arr5.length; i++) {
        System.out.println(arr5[i]);
}

 

12.复制数组;

1
2
3
4
5
6
7
8
//方法 1.
int[] arr6 = {3721};
int[] arr7=Arrays.copyOf(arr6, 10);  //指定新数组的长度
//方法 2.        
int[] arr8=Arrays.copyOfRange(arr6, 13); //只复制从索引[1]到索引[3]之间的元素(不包括索引[3]的元素)
for (int i = 0; i < arr8.length; i++) {
        System.out.println(arr8[i]);
}

 

13.比较两个数组;

1
2
3
int[] arr9 = {1234,5,6,7,8,9,0};
        boolean arr10=Arrays.equals(arr6, arr9);
        System.out.println(arr10);

 

14.去重复;

1
2
3
4
5
6
7
8
9
10
11
12
13
int[] arr11 = {1234,5,6,7,8,9,0,3,2,4,5,6,7,4,32,2,1,1,4,6,3};
//利用set的特性
Set<Integer> set2=new HashSet<Integer>();
for (int i = 0; i < arr11.length; i++) {
    set2.add(arr11[i]);
}
System.out.println(set2);
int[] arr12 = new int[set2.size()];
int j=0;
for (Integer i:set2) {
    arr12[j++]=i;
}
System.out.println(Arrays.toString(arr12));

 

15.查询数组中的最大值和最小值;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int[] arr11 = {10234,5,6,7,8,9,0,3,2,4,5,6,7,4,32,2,1,1,4,6,3};
 //计算最大值
int max = arr11[0];
for (int i = 1; i < arr11.length; i++) {
     if (arr11[i] > max) {
         max = arr11[i];
    }
  }
  System.out.println("Max is " + max);
  //计算最小值
  int min = arr11[0];
  for (int i = 0; i < arr11.length; i++) {
    if (arr11[i]<min) {
        min = arr11[i];
    }
}
  System.out.println("Min is " + min);

 

 

 

posted @ 2017-08-09 15:06  飞教主  阅读(115)  评论(0编辑  收藏  举报