剑指offer-java代码(更新中。。。)

Java (更新中。。。)

读研之后,随导师方向开始接触机器学习,使用的语言也从本科的Java转到了现在的Python,虽说Python简练易懂,但老本行不能丢,多个技能总归是没有错的,所以决定每周末腾出点时间刷几道编程题,起提神醒脑之功效,已经很久没写过java了,这样实在不好,先从剑指offer开始(注:给出的代码并非完善,只列关键代码,因主要想谈谈自己考虑问题的思路,故暂默认是期望输入)!详情见GitHub

第二章:

/*
* 找出数组中重复的数字(长度为n,每个数字在0~n-1的范围内)
*/
int[] in = {2,3,1,0,2,5,3};

for(int i = 0; i < in.length; i++){
    while(i != in[i]){
        if (in[i] == in[in[i]]) {
            System.out.println("find a repeat number:" + in[i]);
            break;
        }
        int k = in[i];
        in[i] = in[k];
        in[k] = k;              
    }
}
/*
* 不修改数组找出重复的数字(长度为n+1,每个数字在1~n的范围内)
* 时间:O(nlogn),空间(优先):O(1)
* 还可以使用辅助空间O(n),时间上会更快些
*/
int[] in = {2,3,5,4,3,2,6,7};
int start = 1;
int end = 7;
while(start <= end){
      int middle = (start + end) / 2;
      System.out.println("middle:"+middle);
      int count = count_number(in, 8, start, middle);
      System.out.println("count:"+count);
      if(start == end){
          if(count > 1){
              System.out.println("find a repeat number:" + start);
              break;
          }else{
              System.out.println("have no repeat numbers!");
              break;
          }
      }
      if(count > (middle-start+1)){
          end = middle;
      }else{
          start = middle + 1;
      }
}
public static int count_number(int in[], int lengh, int start, int end) {
        // TODO Auto-generated method stub
        int count = 0;
        for(int i = 0; i < lengh;i++){
            if(in[i] >= start && in[i] <= end){
                count++;
            }
        }
        return count;
}
/*
*二维数组,每行每列,从左到右,从上到下,按递增顺序排列 ,判断某数字是否在该数组中
*注:谈下我一开始的思路:
*   1.遍历第一行,直到number>in[0][j],然后只保留0~j-1列,若有相等就直接返回
*   2.遍历第一列,直到number>in[i][0],然后只保留0~i-1列,若有相等就直接返回
*   3.此时,该数字就被锁定到[i][j]矩阵中了
*但仔细想想这样有个极端的问题,该数字若在右下角,其实这样的分割法就毫无意义了
*之后参考了书中思路,恍然大悟,“分割”这个点想到了,但是遍历的路径选错了,感觉有点固定思维了,总是想着从左上角开始遍历
*没有抓住题里给的数字排列顺序背后在规律,今后在处理问题时,应该具有一发散性思维,跳出固定思维处理问题!!!
*/
public static boolean test(int in[][], int r, int c, int number){
        boolean flag = false;
        int i = 0;
        int j = c-1;
        while(i < r && j >= 0){
            if(number == in[i][j]){
                flag = true;
                break;
            }
            if(number < in[i][j]){
                j--;
            }else{
                i++;
            }
        }



        return flag;
}
public String replcae(String str){
        /*
         * 替换空格
         * 我的想法:因为我的基础语言是java,所以我的思路没有像书中一样考虑指针p1,p2,所以最初的想法就是开辟额外空间
         * 然后将对应字符复制过去,即是获取到字符串的空格数,然后重新开辟一个str.length() + countSpace * 2的字符
         * 空间,从前到后扫描源字符串遇到空格依次在新数组中赋值‘%’‘2’‘0’,否则赋值str.charAt(i)
         * 这样重新开辟空间的方法从前到后,和书中从后到前的时间复杂度是一样的,并非在源字符空间上操作
         * 对于java无法在原字符串上扩容
         */
        int countSpace = 0;
        for(int i = 0; i < str.length(); i++){
            if(str.charAt(i) == ' '){
                countSpace++;
            }
        }
        int newLengh = str.length() + countSpace * 2;
        char[] ss = new char[newLengh];

        int newIndex = newLengh - 1;
        for(int i = str.length()-1; i >= 0; i--){
            if(str.charAt(i) == ' '){
                ss[newIndex--] = '0';
                ss[newIndex--] = '2';
                ss[newIndex--] = '%';
            }else{
                ss[newIndex--] = str.charAt(i);
            }           
        }
        return new String(ss);      
    }

猜你喜欢

转载自blog.csdn.net/Joker_sir5/article/details/82558977
今日推荐