一刷剑指Offer:数组专题

二、数组专题

1、剑指Offer_04:二维数组的查找

题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整

public class Solution {
    public boolean Find(int target, int [][] array) {
        /**
         * 考查二维数组的遍历
         */
        for(int i=0;i<array.length;i++){
            for(int j=0; j<array[0].length;j++){
                if(array[i][j]==target){
                    return true;
                }
            }
        }
        return false;
    }
}

2、剑指Offer_03:数组汇总重复的数字

题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内,数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。

例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

public class Solution {
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers==null){
            return false;
        }
        Arrays.sort(numbers);
        for(int i=0;i<length;i++){
            if(i!=0 && numbers[i]==numbers[i-1]){
                duplication[0] = numbers[i];
                return true;
            }
        }
        return false;
    }
}

3、剑指Offer_66:构建乘积数组

题目:给定一个数组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];)

public class Solution {
    public int[] multiply(int[] A) {
        int[] B = new int[A.length];

        //B[0] = A[1] * A[2] * ... * A[n-1]
        B[0] = 1;
        for(int i=1;i<A.length;i++){
            B[0] *= A[i];
        }

        //B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]
        int j=1;
        while (j<B.length-1){
            B[j]= 1;
            for(int i=0;i<A.length;i++){
                if(i<j){
                    B[j] *= A[i];
                }
                 if(i>j){
                     B[j] *= A[i];
                 }
            }
            j++;
        }

        //B[n-1] = A[0] * A[1] * ... * A[n-2];
        B[B.length-1] = 1;
        for(int i=0;i<A.length-1;i++){
            B[B.length-1] *= A[i] ;
        }
        return B;
    }
}

4、剑指Offer_21:调整数组顺序使得奇数位于偶数前面

题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
在这里插入图片描述

public class Solution {
    public void reOrderArray(int [] array) {
        //记录已放好位置奇数的个数
        int k = 0;
        for(int i=0;i<array.length;i++){
            if(array[i]%2==1){
                int index = i;
                while (index>k){
                    int tmp = array[index];
                    array[index] = array[index-1];
                    array[index-1] = tmp;
                    index--;
                }
                k++;
            }
        }
    }
}

5、剑指Offer_29:顺时针打印矩阵

题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
在这里插入图片描述

public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        //左边界
        int left = 0;
        //右边界
        int right = matrix[0].length-1;
        //上边界
        int top = 0;
        //下边界
        int bottom = matrix.length-1;

        /**
         * 由外到内顺时针打印矩阵:每一层都按照下面的顺序进行打印
         * 1、从左到右打印,打印后top+1; top>bottom跳出循环
         * 2、从上到下打印,打印后right-1; right<left跳出循环
         * 3、从右向左打印,打印后bottom-1; bottom<top跳出循环
         * 4、从下向上打印,打印后left+1; left>right跳出循环
         */
        while(true){
            for(int i=left;i<=right;i++){
                list.add(matrix[top][i]);
            }
            top++;
            if(top>bottom) break;

            for(int i=top;i<=bottom;i++){
                list.add(matrix[i][right]);
            }
            right--;
            if(right<left) break;

            for(int i=right;i>=left;i--){
                list.add(matrix[bottom][i]);
            }
            bottom--;
            if(bottom<top) break;

            for(int i=bottom;i>=top;i--){
                list.add(matrix[i][left]);
            }
            left++;
            if(left>right) break;
        }
        return list;
    }
}

6、剑指Offer_42:连续子数组的最大和

题目:输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZTVhLctC-1587999702646)(C:\Users\hh\Desktop\秋招面试准备\assets\image-20200427214918980.png)]

思路:如果dp[i-1]>0就继续累加,反之舍弃之前的累加和,重新开始累加。

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        /**
         * 动态规划问题:
         * 1、dp[i]代表连续子数组的最大和
         * 2、如果array[i] < dp[i-1]+array[i] 那么dp[i]=dp[i-1]+array[i],起到了正贡献就留着
         * 3、如果array[i] >= dp[i-1]+array[i] 那么dp[i]=array[i],起到了负贡献就丢弃
         */
        int[] dp = new int[array.length];
        int result = Integer.MIN_VALUE;
        for(int i=0;i<array.length;i++){
            if(i==0){
                dp[i] = array[i];
            }else{
                if(array[i]<dp[i-1]+array[i]){
                    dp[i]=dp[i-1]+array[i];
                }else{
                    dp[i]=array[i];
                }
            }
            result = Math.max(result,dp[i]);
        }
        return result;
    }
}

7、剑指Offer_45:把数组排成最小的数

题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

import java.util.Arrays;
import java.util.Comparator;

/**
 * 在排序时传入一个自定义的Comparator实现,重新定义String类内的排序方法,
 * 若拼接s1+s2 > s2+s1,那么把s2在拼接时放在前面,以此类推,将整个String列表排序后再拼接起来。
 * 如:3、32--- 332>323 ---323
 */
public class Solution {
    public String PrintMinNumber(int [] numbers) {
        
        /**
         * 1、将整型数组转换为字符串数组
         */
        String[] str = new String[numbers.length];
        for(int i=0;i<numbers.length;i++){
            str[i] = String.valueOf(numbers[i]);
        }

        /**
         * 2、自定义比较器比较拼接后字符串
         *  public int compareTo( NumberSubClass referenceName )
         *  如果指定的数大于参数返回1: System.out.println(5.compareTo(3)); //1  排序为:3、5
         */
        Arrays.sort(str, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return (o1+o2).compareTo(o2+o1);
            }
        });

        /**
         *3、将字符串数组拼接成字符串
         */
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<str.length;i++){
            sb.append(str[i]);
        }
        
        return sb.toString();
    }
}
原创文章 723 获赞 153 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_42764468/article/details/105802224