内螺旋矩阵等逻辑题

来源:互联网 发布:京东店铺数据分析报告 编辑:程序博客网 时间:2024/05/21 15:42

有序数组中数字的出现次数
November 2nd, 2011 leeing No comments
据说是微软的一道题。

题目:在排序数组中,找出给定数字的出现次数,比如 [1, 2, 2, 2, 3] 中2的出现次数是3次。

算法的思想,使用修改后的二分查找法,找到最左边 2 的下标为 1 ,最后边 2 的下标为 3,然后返回3 – 1 + 1 = 3 即可,算法复杂度为 logN。

编码的时候,用一个变量 last 来存储本次查找到的位置,然后根据情况变换查找方向,就可以分别确定 left 和 right 下标的值。

代码实现:

view sourceprint?01 package org.leeing.interview; 

02   

03 /** 

04  * 题目:在排序数组中,找出给定数字的出现次数,比如 [1, 2, 2, 2, 3] 

05  * 2 的出现次数是3次。 

06  * 

07  * @author leeing 

08  * 

09  */

10 public class NumberCounter { 

11     public static void main(String[] args) { 

12         int a[] = { 1, 2, 2, 2, 2, 3, 4 }; 

13         int counter = numbercounter(a, 4); 

14         System.out.println(counter); 

15     } 

16   

17     static int numbercounter(int[] a, int num) { 

18         int left = binarysearch(a, num, true); 

19         int right = binarysearch(a, num, false); 

20         System.out.println("left is :" + left); 

21         System.out.println("right is :" + right); 

22   

23         if (left != -1 && right != -1) { 

24             return right - left + 1; 

25         } else { 

26             return 0; 

27         } 

28     } 

29   

30     static int binarysearch(int[] a, int target, boolean isLeft) { 

31         int left = 0, right = a.length - 1; 

32         int last = 0; 

33         while (left <= right) { 

34             int mid = (left + right) / 2; 

35             if (a[mid] < target) { 

36                 left = mid + 1; 

37             } else if (a[mid] > target) { 

38                 right = mid - 1; 

39             } else { 

40                 last = mid; 

41   

42                 if (isLeft) { 

43                     right = mid - 1; 

44                 } else { 

45                     left = mid + 1; 

46                 } 

47             } 

48         } 

49         return last > 0 ? last : -1; 

50     } 

51 }
Categories: 面试 Tags: 面试
内螺旋矩阵
October 31st, 2011 leeing No comments
暂且就叫内螺旋矩阵吧。

view sourceprint?01 int i=5; 

02 1  2  3  4  5

03 16 17 18 19 6

04 15 24 25 20 7

05 14 23 22 21 8

06 13 12 11 10 9

07   

08 int i=6

09 1  2  3  4  5   6

10 20 21 22 23 24  7

11 19 32 33 34 25  8

12 18 31 36 35 26  9

13 17 30 29 28 27 10

14 16 15 14 13 12 11

最近常在网上看到一些打印矩阵的题,后来发现其实都是有相同的规律可循的:

1. 将问题转化为初始化矩阵的问题,然后模拟行走的方向,一般来说,方向都是循环的,而每次行走的步数也是按一定的规律递减,比如当i = 5 时:

view sourceprint?1 向右 5 步 

2 向下 4 步 

3 向左 4 步 

4 向上 3 步 

5 向右 3 步 

6 向下 2 步 

7 向左 2 步 

8 向上 1 步 

9 向右 1 步

很明显吧?544332211,右下左上,右下左上…

2. 在编程时,我们可以用一个整数 direction 来记录方向,每到当前方向的最后一步,就转变方向。由于方向都是按一定的次序循环的,所以,在转换方向时,可以用:

direction = (direction+1)%4。

代码如下:

Read more…
Categories: 面试 Tags: Java
三角螺旋矩阵
October 18th, 2011 leeing No comments
据说是Yahoo的一道题,题目如下:

打印如下矩阵,如果 n=7 则输出:

view sourceprint?1 1

2 2   18

3 3   19  17

4 4   20  27  16

5 5   21  28  26  15

6 6   22  23  24  25  14

7 7   8   9   10  11  12  13

 

注意观察可知,数字增加的方向及走过的步数是有规律的:

 

view sourceprint?1 向下 7 步 

2 向右 6 步 

3 斜上 5 步 

4 向下 4 步 

5 向右 3 步 

6 斜上 2 步 

7 向下 1 步

 

所以可以设定的一个变量 direction 记录方向的变化,循环变化。

同时根据 direction 的不同,来决定每次的递增位置。

Read more…
Categories: Java, 面试 Tags: Java, 面试
对称矩阵
October 17th, 2011 leeing No comments
有道的面试题。

写一个函数,打印一个如下的 n x n 的矩阵:

 

view sourceprint?01 n = 5

02   

03 1 1 1 1 1

04 1 2 3 2 1

05 1 3 6 3 1

06 1 2 3 2 1

07 1 1 1 1 1

08   

09 n = 6

10   

11 1 1 1 1 1 1

12 1 2 3 3 2 1

13 1 3 6 6 3 1

14 1 3 6 6 3 1

15 1 2 3 3 2 1

16 1 1 1 1 1 1

提示: 除了边上的元素,每个元素都是由边上的某两个元素相加得到的。

观察一下即知这个矩阵具有一定的对称性,那么只要求取左上角的子矩阵,再通过对称即可得到整个矩阵。

view sourceprint?01 package org.leeing.matrix; 

02   

03 public class Matrix { 

04     public static void main(String[] args) { 

05         printMatrix(5); 

06     } 

07   

08     private static void printMatrix(int num) { 

09         int matrix[][] = new int[num][num]; 

10         int len = (int)Math.ceil(num/2.0); 

11         for(int j = 0;j<len;j++){
// 边赋值为1 

12             matrix[0][j] = 1; 

13             matrix[j][0] = 1; 

14         } 

15   

16         for(int i = 1;i&ltlen ;i++){
// 求和 

17             for(int j =1;j<len;j++) 

18                 matrix[i][j] = matrix[i-1][j] + matrix[i][j-1]; 

19         } 

20   

21         for(int i = 0;i<len;i++){
// 左右对称 

22             for(int j = len;j<num;j++){ 

23                 matrix[i][j] = matrix[i][num-j-1]; 

24             } 

25         } 

26   

27         for(int i = len;i<num;i++){
//上下对称 

28             for(int j = 0;j<num;j++){ 

29                 matrix[i][j] = matrix[num-i-1][j]; 

30             } 

31         } 

32   

33         for(int i = 0;i<num;i++){ 

34             for(int j = 0;j<num;j++){ 

35                 System.out.print(matrix[i][j]+"\t"); 

36             } 

37             System.out.println(); 

38         } 

39         System.out.println(); 

40     } 

41 }

 

原创粉丝点击