数组

1.顺时针打印数组 

  eg: 1 2 3

      4 5 6

      7 8 9  打印出来,结果为1 2 3 6 9 8 7 4 5

  解: 注意 * * (只有一行) 只有一列,行列不同等情况。

 1 package offer;
 2 
 3 /**
 4  * 剑指offer p127 20题
 5  * @author hasee
 6  *
 7  */
 8 public class PrintArr {
 9     public static void print(int[][] arr){
10         if(arr == null)
11             return;
12         int width = arr[0].length,high = arr.length;
13         int x=0,y=0;
14         while (width>0 && high>0) {
15             for (int i = 0; i < width; i++) 
16                 System.out.print(arr[x][y+i]+" ");
17             for (int i = 1; i < high; i++) 
18                 System.out.print(arr[x+i][y+width-1]+" ");
19             //错误! for循环前必须加上if判断
20             //当只有一行时,这里不该打印,因为width和行无关
21             if(high>1) for (int i = width-2; i >= 0; i--) 
22                 System.out.print(arr[x+high-1][y+i]+" ");
23             //当只有一列时,这里不该打印,因为high和列无关
24             if(width>1) for (int i = high-2; i >= 1; i--) 
25                 System.out.print(arr[x+i][y]+" ");
26             System.out.println();
27             x++;
28             y++;
29             width-=2;
30             high-=2;
31         }
32     }
33     public static void main(String[] args) {
34         int[][] arr = new int[1][1];
35         for (int i = 1; i <= arr.length; i++) {
36             for (int j = 1; j <= arr[0].length; j++) {
37                 arr[i-1][j-1] = (i-1)*arr[0].length+j;
38             }
39         }
40         print(arr);
41     }
42 }
View Code

 2.数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点

 1 package number;
 2 
 3 /**
 4  * 数轴上从左到右有n各点a[0], a[1], ……,a[n -1],给定一根长度为L的绳子,求绳子最多能覆盖其中的几个点。
 5  * @author hasee
 6  *
 7  */
 8 public class MaxTimesOfL {
 9     public static void main(String[] args) {
10         int[] arr = {-1, 0, 3, 9, 11, 13, 14, 25};//数轴上的点  
11         System.out.println(mostCover(arr,5));
12     }
13     /**
14      * 两个指针,一个front,一个rear,每次front-rear,比L小,看覆盖的点数。
15      * 保存覆盖点数的最大值,然后front++;比L大,rear++,每个数最多遍历2遍,复杂度O(N)。
16      * 对于这个算法,他给了一个形象的比喻:
17      * 就好像一条长度为L的蛇。头伸不过去的话,就把尾巴缩过来最多只需要走一次,就知道能覆盖几个点
18      * 参考自:http://blog.csdn.net/thebestdavid/article/details/12236687
19      * @param arr
20      * @param n
21      * @return
22      */
23     public static int mostCover(int[] arr,int n){
24         if (arr == null) 
25             return -1;
26         //两个指针,指向头节点和尾节点,动态判断是否超过n来计算包含的点个数
27         //有点类似快速排序的双指针向前走
28         int head=0,rear=0; 
29         int max=0;
30         while (rear<arr.length) {
31             if (arr[rear]-arr[head] > n) {
32                 //此处错误,先前是rear-head+1,因为已经大于n了 所以不应该加一
33                 max = max<rear-head ? rear-head : max;
34                 head++;
35             }else
36                 rear++;
37         }
38         return max;
39     } 
40     
41 }
View Code

 3.给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,他们的和为X,bool judge(int *a, int len, int x),存在返回true,不存在返回false

 1 package nothing;
 2 
 3 /**
 4  * 给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,
 5  * 他们的和为X,bool judge(int *a, int len, int x),存在返回true,不存在返回false
 6  * @author hasee
 7  *
 8  */
 9 public class Manacher {
10     public static void main(String[] args) {
11         int[] arr = {1,4,6,7,9,11,15};
12         System.out.println(isHaveSum(arr,6));
13     }
14 
15     private static boolean isHaveSum(int[] arr, int sum) {
16         if(arr == null)
17             return false;
18         int head=0,tail=arr.length-1; //喜闻乐见的双指针,头尾,有点像二分查找
19         while(head<tail){
20             if(arr[head]+arr[tail]<sum)
21                 head++;
22             else if(arr[head]+arr[tail]>sum)
23                 tail--;
24             else
25                 return true;
26         }
27         return false;
28     }
29     
30 }
View Code

 4.发帖水王变体

  随着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗?

参见:http://blog.csdn.net/whz_zb/article/details/7436045

  分析:在这个题目中,有一个计算机科学中很普遍的思想,就是如何把一个问题转化为规模较小的若干个问题。分治、递推和贪心等都有这样的思想。在转化过程中,如果能保证小的问题跟原问题的解是一致的就成功了。这样,我们可以通过寻找这样的方式将小问题转化为更小的问题。如何将大问题拆成小问题,或者如何大规模的数据降成小规模,而不影响解呢?

  题思路:其实想想,不同于三个数的剩下的数只占总数的1/4不到。。所以直接用3个数记录,不同于这3个数就集体都减一,最后留下的肯定是这3个数。

  

原文地址:https://www.cnblogs.com/jslee/p/3477206.html