剑指offer数组专题 (java)

19 篇文章 0 订阅

1.在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例1
输入:7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值:true

//思路
 public boolean Find(int target, int [][] array) {
        for(int i = 0;i <array.length;i++){
            for(int j =0;j< array.length;j++){
                if(array[i][i] == target){
                    return true;
                }
            }
        }
        return false;
        //解题
         public boolean Find(int target, int [][] array) {
        if(array.length == 0 || array[0].length == 0) return false;
        int leni = array.length;
        int lenj = array[0].length;
        int i = 0;
        int j = lenj -1;
        while(i < leni && j >=0){
            if(target == array[i][j]){
                return true;
            }else if(target < array[i][j]){
                j--;
            }else{
                i++;
            }
        }
        return false;
}

7.大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n\leq 39n≤39
示例1
输入:4
返回值:3

//思路
public int Fibonacci(int n) {
        if(n <2 ) return n;
       int i = 0;
       int k =0,num =1;
       while(k <=n){
           num += i;
           i = num;
           k++;
       }
        return num;
    }
     public int Fibonacci(int n) {
       if(n <2 ) return n;
           int i = 0,j = 1;
       int k =1,num =0;
       while(k <n){
           num = i+j;
           i = j;
           j = num;
           k++;
       }   
        return num;
    }
    //递归
      public int Fibonacci(int n) {
       if(n < 2) return n;
        return Fibonacci(n-1)+Fibonacci(n-2);
    }

13.输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

//思路
public void reOrderArray(int [] array) {
        String sc = array.toString();
        for(int i = 0;i < sc.length();i++){
            if((sc.charAt(i)-'0')%2 ==0){
                sc.delect(sc.charAt(i));
                sc.append(sc.charAt(i));
            }
        }
    }
    public void reOrderArray(int [] array) {
      int len = array.length;
      for(int k = 1; k < len ;k++){
          int i = k;
          if(array[i]%2 == 1){
              while(i>0 && (array[i-1] %2) != 1){
                  int temp = array[i-1];
                  array[i-1] = array[i];
                  array[i] = temp;
                  i--;
              }
          }
      }
    }
    

19.输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
示例1
输入:[[1,2],[3,4]]
返回值:[1,2,4,3]

 public ArrayList<Integer> printMatrix(int [][] matrix) {
       if(matrix == null || matrix.length == 0 || matrix[0].length ==0 || matrix[0] == null){
           return null;
       }
        int rows = matrix.length;
        int col = matrix[0].length;
        int start = 0;
        ArrayList<Integer> pre = new ArrayList<Integer>();
        while(rows>0 && col >0){
            printMatrix(matrix,start,col,rows,pre);
            rows -= 2;
            col -= 2;
            
            start++;
        }
        return pre;
    }
    public void printMatrix(int [][] matrix,int start,int col,int rows,ArrayList<Integer> pre){
        for(int i = 0; i < col;i++){
            pre.add(matrix[start][start+i]);
        }
        for(int j=0; j < rows-2 ;j++){
            pre.add(matrix[start+1+j][start+col-1]);
        }
        for(int i = 0;i < col && rows != 1;i++){
            pre.add(matrix[start+rows-1][start+col-1-i]);
        }
        for(int j = 0 ;j < rows-2 && col != 1;j++){
            pre.add(matrix[start+rows-j-2][start]);
        }
    }

28.数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
示例1
输入:[1,2,3,2,2,2,5,4,2]
返回值:2

//思路
  public int MoreThanHalfNum_Solution(int [] array) {
        if(array == null || array.length == 0) return 0;
        int len = array.length;
        int count =0;
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        for(int i =0; i < len;i++){
            if(!map.contains(array[i])){
                
                count++;
            }
            map.put(array[i],count);
        }
        for(int i = 0 ;i < len;i++){
            if(map.getKey(i) > len/2) return map.
        }
        return 0;
    }
     public int MoreThanHalfNum_Solution(int [] array) {
        if(array == null || array.length == 0) return 0;
        if(array.length == 1) return array[0];
        int [] tmp = new int[10];
        for(int i = 0;i <array.length;i++){
            tmp[array[i]]++;
            if(tmp[array[i]] >array.length/2){
                return array[i];
            }
        }
        return 0;
    }

32.输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
示例1
输入
[3,32,321]
返回值
“321323”

Integer.valueOf()的作用是字符串转成int
 String.valueOf()的作用是int转字符串
   public String PrintMinNumber(int [] numbers) {
        String str ="";
        if(numbers == null || numbers.length ==0) return "";
        int len = numbers.length;
        for(int i =0 ; i <len;i++){
            for(int j = i+1;j<len; j++){
                int a = Integer.valueOf(numbers[i]+ ""+numbers[j]);
                int b = Integer.valueOf(numbers[j]+ ""+numbers[i]);
                if(a>b){
                    int tmp = numbers[i];
                    numbers[i] = numbers[j];
                    numbers[j]= tmp;
                }
            }
        }
        for(int k = 0;k< len;k++){
            str += String.valueOf(numbers[k]);
        }
        return str;
    }

35.在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
对于50%50%的数据,size\leq 10^4size≤10 的4次方
对于75%75%的数据,size\leq 10^5size≤10 的5次方
对于100%100%的数据,size\leq 2*10^5size≤2∗10 的5次方
题目保证输入的数组中没有的相同的数字
示例1
输入:[1,2,3,4,5,6,7,0]
返回值:7

时间复杂度太大
  public int InversePairs(int [] array) {
        int i = 0,count = 0;
        while(i<array.length){
            for(int j = i+1;j<array.length;j++){
                if(array[j] > array[i]){
                    count++;
                }
            }
            i++;
        }
        return count%1000000007;
    }
    归并排序
      int count = 0;
    public int InversePairs(int [] array) {
     if(array == null || array.length ==0) return 0;
     int [] tmp = new int[array.length];
     mergesort(array,0,array.length-1,tmp);
     return count;
    }
    public void mergesort(int [] array,int start, int end,int [] tmp){
        if(start < end){
            int mid = (start +end)/2;
            mergesort(array,start,mid,tmp);
            mergesort(array,mid+1,end,tmp);
            merge(array,start,end,tmp);
        }
    }
    public void merge(int [] array,int start,int end,int [] tmp){
        int mid = (start + end)/2;
        int i = start;
        int j = mid+1;
        int k = start;
        while(i<=mid && j<= end){
            if(array[i] < array[j]){
                tmp[k++] = array[i++];
            }else{
                tmp[k++] = array[j++];
                count += mid -i+1;
                count = count%1000000007;
            }
        }
            while(i <= mid){
                tmp[k++] = array[i++];
            }
            while(j <= end){
                tmp[k++] = array[j++];
            }
            for(int l =start;l <= end;l++){
                array[l]= tmp[l] ;
            }
    }

37.题目描述
统计一个数字在升序数组中出现的次数。
示例1
输入:[1,2,3,3,3,3,4,5],3
返回值:4

 public int GetNumberOfK(int [] array , int k) {
       if(array == null || array.length == 0) return 0;
        int count =0;
        int left = 0,right = array.length
        int mid = (left + right)/2;
        while(left <= mid && mid <= right){
            
        }
        return count;
    }

42.输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
返回值描述:对应每个测试案例,输出两个数,小的先输出。
示例1
输入:[1,2,4,7,11,15],15
返回值:[4,11]

思路
public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> res = new ArrayList<Integer>();
        if(array == null || array.length == 0) return res;
        int i = 0;
        while(i < array.length){
            for(int j = i+1;j <array.length;j++){
                if(array[i] + array[j] == sum){
                    int num = array[i] * array[j];
                    
                }
            }
            i++;
        }
    }
     public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
       ArrayList<Integer> res = new ArrayList<Integer>();
       if(array == null || array.length == 0) return res;
       int i =0,j = array.length-1;
       while(i< j){
           if(array[i] + array[j] > sum){
               j--;
           }else if(array[i] + array[j] <sum){
               i++;
           }else{
               res.add(array[i]);
               res.add(array[j]);
               return res;
           }
       }
        return res;
    }

51.给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
示例1
输入:[1,2,3,4,5]
返回值:[120,60,40,30,24]

思路
   public int[] multiply(int[] A) {
        int [] res = new int[A.length];
        if(A.length < 2) return res;
        int len = A.length;
        for(int i = 1; i< len; i++){
            res[0] = 1;
            res[0] *= A[i];
        }
        int k = 2;
        while(k<= len){
            for(int j =0; j <len-1;j++){
                res[k-1] = 1;
                res[k-1] *= A[j];
            }
            k++;
        }
        return res;
    }
      public int[] multiply(int[] A) {
        int [] res = new int[A.length];
        int tmp =0;
        if(A.length < 2) return res;
        int len = A.length;
        for(int i = 0; i< len; i++){
            tmp = A[i];
            A[i] = 1;
            res[i] = 1;
            for(int j = 0; j <len;j++){
                res[i] *= A[j];
            }
            A[i] = tmp;
    }
        return res;
   }

66.地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
示例1
输入:5,10,10
返回值:21

  public int movingCount(int threshold, int rows, int cols){
        boolean[] flag = new boolean[rows*cols];
        int count = movingCountCore(threshold,rows,cols,0,0,flag);
        return count;
    }
    public int movingCountCore(int threshold,int rows,int cols,int i,int j,boolean[] flag){
        int count = 0;
        int index = i*cols + j;
        if(i <0 || i> rows-1 || j <0|| j > cols -1 || flag[index] == true ||getnum(i,j) >threshold){
            return count;
        }
        flag[index] = true;
        count = 1 + movingCountCore(threshold,rows,cols,i+1,j,flag)+ 
                    movingCountCore(threshold,rows,cols,i-1,j,flag)+
                    movingCountCore(threshold,rows,cols,i,j+1,flag)+
                    movingCountCore(threshold,rows,cols,i,j-1,flag);
        return count;
    }
    public int getnum(int i,int j){
      int m = 0,n = 0;
        while(i >0){
            m += i %10;
            i = i/10;
        }
        while( j >0){
            n += j%10;
            j = j/10;
        }
        return m +n;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值