剑指offer题目整理

1、将一个字符串转乘整数

例如“1234”->1234

 1     public static void main(String[] args){
 2         String s = "1234";
 3         int cur = 0;
 4         int number = 0;
 5         while ( cur < s.length() ){
 6             number = number * 10 + s.charAt(cur) - '0';
 7             cur ++;
 8         }
 9         System.out.println(number);
10     }

现在研究这段代码,有什么问题呢?首先,没有判断正负号,如果输入是“-1234”,就错了;其次,没有考虑int变量的范围,如果超过Integer.maxvalue,程序就会崩溃;最后就是如果输入有特殊字符,比如输入“123#¥%34”,这个时候应该怎么把。哦,还有最重要的一点,如果输入s是空怎么办。

2、求链表倒数第k个节点

思路:两个指针,第一个指针先走k-1步,然后两个指针一起走。

学习前面的思路,这里会有哪些特殊情况呢?首先,链表为空是一种特殊情况;其次,如果链表总长度比k要小,又是一种特殊情况;最后,输入的k为0,又是一种特殊情况。

 1 public int lastknode(ListNode head ,int k){
 2         if ( head == null ) return 0;
 3         ListNode p = head;
 4         ListNode q = head;
 5         if ( k > 0 ){
 6             for ( int i = 0 ; i < k - 1 ; i ++ ) {
 7                 if (p.next == null) return 0;
 8                 p = p.next;
 9             }
10         }
11         while ( p.next != null ){
12             p = p.next;
13             q = q.next;
14         }
15         return q.val;
16     }

这个代码里面倒数第0个和倒数第1个指向的都是一个节点。。

3、二维数组中查找

题目:在一个二维数组中,每一行都按照从左到右递增的顺序,每一列都按照从上到下递增的顺序排列。给一个整数,要求判断数组中是否存在这个数字。

分析:如果是一维数组,有序情况下,最快的方法就是二分查找。但是这里是二维数组,做法其实和二分类似了,都是不断的缩小查找的范围。

比如这样一个数组:

1   2   8   9                             1   2  8   9                             1   2  8   9

2   4   9   12                           2   4   9   12                          2   4   9   12

4   7   10   13                         4   7   10   13                        4   7   10   13

6   8   11   15                         6   8   11   15                         6   8   11   15

假如我们要找7,那么如何缩小查找的范围呢。因为左到右,上到下都是递增的。

首先我们考虑如何缩减列,所以第一行8>7,那么8以及8以后的列数就可以忽略了,因为这两列一定都>=8,所以变成第二个数组,灰色部分就是可以忽略的列数部分。这里要注意用一个指针rightedge指向新数组最外面一列。

然后我们考虑如何缩减行,同样的办法,对于rightedge列,从上到下遍历,可以删去两行,如第三个数组所示,浅蓝色部分就是可以忽略的行数部分。这里同样用一个指针downedge来指向新数组的最上面的一行。

这样我们就只需要对左下角这个无色的数组进行遍历寻找就可以了。这里要注意在找列和行的过程中要考虑正好是target值。

 1     public boolean findin2D(int[][] nums, int target){
 2         if ( nums[0][0] > target ) return false;
 3         int rightedge = 0,downedge = 0;
 4         for ( int i = 0 ; i < nums[0].length ; i ++ ){
 5             if ( nums[0][i] == target ) return true;
 6             if ( nums[0][i] < target ) rightedge = i ;
 7         }
 8         for ( int j = 0 ; j < nums.length ; j ++ ){
 9             if ( nums[rightedge][j] == target ) return true;
10             if ( nums[rightedge][j] < target ) downedge = j + 1;
11         }
12         for ( int i = downedge ; i < nums.length ; i ++ ){
13             for ( int j = 0 ; j <= rightedge ; j ++  ){
14                 if ( nums[i][j] == target ) return true;
15             }
16         }
17         return false;
18     }

猜你喜欢

转载自www.cnblogs.com/boris1221/p/9376788.html