剑指offer题目——数字在排序数组中出现的次数

题目:统计一个数字在排序数组中出现的次数,例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4。
最普通的解法

思路:顺序扫描,用一个计数器来记录这个数在这个数组中出现的次数。代码如下:

    public int getNUmber(int data,int a[]){
        int number=0;
        if(a==null){
            return -1;
        }else{
            for(int i=0;i<a.length;i++){
                if(a[i]==data){
                    number++;
                }
            }
        }
        return number;
}

进阶解法

思路:采用二分查找,具体思路可以查看《剑指offer》,现在我将代码展示如下:

public int number(int data,int a[]){
    return getLast(data, a)-getFirst(data, a)+1;
}
/**
 * 数字在排序数组中第一次出现的索引
 */
private int getFirst(int data,int a[]){
    int firstIndex=-1;
    int low=0,high=a.length-1,mid=0;
    while(low<=high){
        mid=(low+high)/2;

        if(data<a[mid]){
            high=mid-1;
        }else if(data>a[mid]){
            low=mid+1;
        }else{
            if(mid>=1&&a[mid-1]==data){
                high=high-1;
            }else{
                return mid;
            }
        }
    }
    return firstIndex;
}
/**
 * 数字在排序数组中最后一次出现的索引
 * @param data
 * @param a
 * @return
 */
private int getLast(int data,int a[]){
    int LastIndex=-1;
    int low=0,high=a.length-1,mid=0;
    while(low<=high){
        mid=(low+high)/2;

        if(data<a[mid]){
            high=mid-1;
        }else if(data>a[mid]){
            low=mid+1;
        }else{
            if(mid<=a.length-2&&a[mid+1]==data){
                low=low+1;
            }else{
                return mid;
            }
        }
    }
    return LastIndex;
}

面向对象的解法

以上的代码最主要是针对某一特定类型,不能够很好地应用到多种数据类型,所以我采用了泛型的用法,使之能够运用到多种数据类型,代码如下:

package com.qiao.offer;

public class Arrays<T extends Comparable<T>> {
public int number(T data,T a[]){
    if(data==null||a==null){
        return -1;
    }
    return getLast(data, a)-getFirst(data, a)+1;
}
/**
 * 数字在排序数组中第一次出现的索引
 */
private int getFirst(T data,T a[]){
    int firstIndex=-1;
    int low=0,high=a.length-1,mid=0;
    if(data==null||a==null){
        return -1;
    }
    while(low<=high){
        mid=(low+high)/2;

        if(data.compareTo(a[mid])<0){
            high=mid-1;
        }else if(data.compareTo(a[mid])>0){
            low=mid+1;
        }else{
            if(mid>=1&&a[mid-1]==data){
                high=high-1;
            }else{
                return mid;
            }
        }
    }
    return firstIndex;
}
/**
 * 数字在排序数组中最后一次出现的索引
 * @param data
 * @param a
 * @return
 */
private int getLast(T data,T a[]){
    int LastIndex=-1;
    int low=0,high=a.length-1,mid=0;
    if(data==null||a==null){
        return -1;
    }
    while(low<=high){
        mid=(low+high)/2;

        if(data.compareTo(a[mid])<0){
            high=mid-1;
        }else if(data.compareTo(a[mid])>0){
            low=mid+1;
        }else{
            if(mid<=a.length-2&&a[mid+1]==data){
                low=low+1;
            }else{
                return mid;
            }
        }
    }
    return LastIndex;
}

}

测试用例如下:

    public static void main(String[] args) {
    Arrays arrays=new Arrays();
    //测试用例(功能测试,边界值测试,特殊输入测试)
    /**
     * 1、没有值;
     * 2、有一个值(普通值,最小值,最大值)
     * 3、有多个值
     */
    Integer a[]={1,2,3,3,3,3,4,5};
    String b[]={"a","b","c","c","c","c","d","d"};

    System.out.println(arrays.number("c", b));
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值