面试题 10.05. 稀疏数组搜索

面试题 10.05. 稀疏数组搜索

稀疏数组搜索。有个排好序的字符串数组,其中散布着一些空字符串,编写一种方法,找出给定字符串的位置。

示例1:

 输入: words = ["at", "", "", "", "ball", "", "", "car", "", "","dad", "", ""], s = "ta"
 输出:-1
 说明: 不存在返回-1。
示例2:

 输入:words = ["at", "", "", "", "ball", "", "", "car", "", "","dad", "", ""], s = "ball"
 输出:4
提示:

words的长度在[1, 1000000]之间

方法1

     public int findString(String[] words, String s) {
            int n = words.length, l = 0, r = n - 1;
            while (l < r) {//退出条件为l==r
                int m = l + (r - l) / 2;//下取整
                int t = m;//存下来m的值
                while (m < r && words[m].equals("")) m++;
                if (r == m) {//m一直向右边滑动到r位置,都是空格
                    r = t - 1;//[t,r]都是空格,这段区间可以被排除掉
                    continue;
                }
                //m已经被筛选出来了, r l 的缩放区间可以不用再考虑m
                if (words[m].equals(s)) return m;
                else if (s.compareTo(words[m]) > 0) {
                    l = m + 1;
                } else {
                    r = m - 1;
                }
            }
            //因为无法判断l是否满足,需要判断
            return words[l].equals(s) ? l : -1;
        }

方法2

        public int findString(String[] words, String s) {
            int n = words.length, l = 0, r = n - 1;
            while (l <= r) {//退出条件为l>r
                int m = l + (r - l) / 2;//下取整
                int t = m;//存下来m的值
                while (m < r && words[m].equals("")) m++;
                if (r == m) {//m一直向右边滑动到r位置,都是空格
                    r = t - 1;//[t,r]都是空格,这段区间可以被排除掉
                    continue;
                }
                //m已经被筛选出来了, r l 的缩放区间可以不用再考虑m
                if (words[m].equals(s)) return m;
                else if (s.compareTo(words[m]) > 0) {
                    l = m + 1;
                } else {
                    r = m - 1;
                }
            }
            //因为无法判断l是否满足,需要判断
            //因为出口的 l和 r 并不相等,且有可能数组越界
            if (l < n && words[l].equals(s)) return l;
            if (r >= 0 && words[r].equals(s)) return r;
            return -1;
        }
  • 修改自方法2
        public int findString(String[] words, String s) {
            int n = words.length, l = 0, r = n - 1;
            while (l <= r) {//退出条件为l>r
                int m = l + (r - l) / 2;//下取整
                System.out.printf("%d,%d,%d\n", l, m, r);
                int t = m;//存下来m的值
                while (words[m].equals("") && m < r) m++;
                if (words[m].equals("")) {//需要排除掉是否是""的情况
//                if (r == m) {//m一直向右边滑动到r位置,都是空格
                    r = t - 1;//[t,r]都是空格,这段区间可以被排除掉
                    continue;
                }
                //m已经被筛选出来了, r l 的缩放区间可以不用再考虑m
                if (words[m].equals(s)) return m;
                else if (s.compareTo(words[m]) > 0) {
                    l = m + 1;
                } else {
                    r = m - 1;
                }
            }
            //因为无法判断l是否满足,需要判断
            //因为出口的 l和 r 并不相等,且有可能数组越界
//            if (l < n && words[l].equals(s)) return l;
//            if (r >= 0 && words[r].equals(s)) return r;
            return -1;
        }

方法3

public int findString(String[] words, String s) {
    int n = words.length, l = 0, r = n;
    while (l < r) {
        int m = l + (r - l) / 2;
        int t = m;
        while (m < r && words[m].equals("")) {
            m++;
        }
        if (r == m) {
            r = t;
            continue;
        }
        if (words[m].equals(s)) return m;
        else if (words[m].compareTo(s) > 0) r = m;
        else l = m + 1;
    }
    return -1;
}

方法4

public int findString(String[] words, String s) {
    int n = words.length, l = 0, r = n - 1; //对比方法3的r的初始值
    while (l < r) {//退出条件为l==r
        int m = l + (r - l) / 2;//下取整
        int t = m;//存下来m的值
        while (m < r && words[m].equals("")) m++;
        if (r == m) {//m一直向右边滑动到r位置,都是空格
            r = t - 1;//[t,r]都是空格,这段区间可以被排除掉
            continue;
        }
        //m已经被筛选出来了, r l 的缩放区间可以不用再考虑m
        if (words[m].equals(s)) return m;
        else if (s.compareTo(words[m]) > 0) {
            l = m + 1;
        } else {
            r = m - 1;
        }
    }
    //因为无法判断l是否满足,需要判断
    return words[l].equals(s) ? l : -1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值