每日一题 为了工作 2020 0412 第四十一题

Posted walxt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一题 为了工作 2020 0412 第四十一题相关的知识,希望对你有一定的参考价值。

/**
 * 
 *  问题:在有序但含有空的数组中查找字符串
 *
 *  题目:给定一个字符串数组 strs[], 在 strs中有些位置为 null, 但在不为 null的位置上,
 *  其字符串是按照字典顺序由小到大依次出现的。再给定一个字符串str, 请返回 str在strs中
 *  出现的最左的位置。
 *
 *  举例:
 *      strs= [null,"a" ,null,"a" ,null,"b",null,"c"], str="a", 返回1。
 *      strs= [null,"a",null,"a",nu ll,"b" ,nul I, "c"], str=null,只要str为null, 就返回-1。
 *      strs= [null,"a",null,"a",null,"b" ,null,"c"], str="d", 返回-1。
 *      
 *  解答:二分查找
 *  1. 假设在 strs[left .. right]上进行查找的过程, 全局整型变量res表示字符串str在strs中最左
 *  的位置。初始时,left=0, right =strs.length-1 , res=-1。
 *  
 *  2. 令mid=(left+right)/2, 则 strs[mid]为 strs[left .. right]中间位置的字符串。
 *  3. 如果字符串strs[mid]与 str一样,说明找到了str, 令 res=mid 。但要找的是最左的位置,所以
 *  还要在左半区寻找,看有没有更左的 str出现,所以令 right=mid-1, 然后重复步骤2。
 *  4. 如果字符串strs[mid]与 str不一样, 并且 strs[mid]!=null,此时可以比较 strs[mid]和str,
 *  如果strs[mid]的子典顺序比str小,说明整个左半区不会出现str, 需要在右半区寻找,所以令left=mid+1, 然后重复步骤2。
 *  5. 如果字符串strs[mid]与str不一样, 并且 strs[mid]=null,此时从mid开始,从右到左遍历左半区
 *  (即strs[left .. mid])。如果整个左半区都为null, 那么继续用二分的方式在右半区上查找(即令left=mid+1),
 *  然后重复步骤2。如果整个左半区不都为null, 假设从右到左遍历strs[left .. mid]时, 发现第一个不为null
 *  的位置是 i,那么把 str和strs[i]进行比较。如果strs[i]字典顺序小于str, 同样说明整个左半区没有str, 令left=mid+1,
 *  然后重复步骤2。如果strs[i]字典顺序等于str, 说明找到str,令res=mid, 但要找的是最左的位置, 所以还要在strs[left .. i-1]
 *  上寻找, 看有没有更左的str出现, 所以令right=i-1, 然后重复步骤2。如果strs[i]字典顺序大于str,说明strs[i .. right]上
 *  都没有str, 需要在strs[left ..i-1]上,所以令right=i-1,然后重复步骤2。
 * 
 * @author 雪瞳
 *
 */

  

public class GetIndex {
	public static int  getIndex(String strs[],String find){
		if(strs==null||strs.length==0||find==null){
			return -1;
		}
		int res =-1;
		int left = 0;
		int right = strs.length-1;
		
		int mid = 0;
		int i=0;
		
		while(left<=right){
			mid = (left+right)/2;
			if(strs[mid]!=null&&strs[mid]==find){
				res = mid;
				right = mid -1;
			}else if(strs[mid]!=null){
				if(strs[mid].compareTo(find)<0){
					left=mid+1;
				}else{
					right=mid-1;
				}
			}else{
				i = mid;
				//从左开始遍历
				while(strs[i]==null&&--i>=left){
				}
				if(i<left || strs[i].compareTo(find)<0){
					left=mid+1;
				}else{
					res=strs[i].equals(find)?i:res;
					right=i-1;
				}
			}
			
		}

		return res;	
		
	}
	public static void main(String[] args) {
		String str[] = {null,"a" ,null,"a" ,null,"b",null,"c"};
		
		int index = getIndex(str, "b");
		showCharArray(str);
		System.out.println(index);
	}
	
	public static void showCharArray(String array[]){
		for (String arr : array) {
			System.err.print(arr+"	");
		}
		System.out.println();
	}
}

  

以上是关于每日一题 为了工作 2020 0412 第四十一题的主要内容,如果未能解决你的问题,请参考以下文章

每日一题 为了工作 2020 04011 第四十题

每日一题 为了工作 2020 0323 第二十一题

每日一题 为了工作 2020 0418 第四十七题

每日一题 为了工作 2020 0303 第一题

爱创课堂每日一题第四十一天- Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?

每日一题 为了工作 2020 0510 第六十八题