zoukankan      html  css  js  c++  java
  • [折半查找]排序数组中某个元素出现次数

    题目描述:

    统计一个数字在排序数组中出现的次数。
    

    这个问题的初始解法就是,在排序的数组中利用折半查找,这个k之后,然后以这个为中心,分别向左右遍历,统计k出现的次数。

    这种方法虽然利用了折半查抄,使得定位这个元素的时间复杂度为O(logn),但是在以这个元素为中心左右查找的时候,时间复杂度又降低为了O(n),所以总体的时间复杂度还是O(n)。

    新的想法:分别利用两次折半查找,找到k的第一次出现的位置,然后再找到k最后一次出现的位置。这样就能直接的求出k的个数,而不用任何的遍历过程。

    int GetNumberOfK(vector<int> data ,int k) 
    {
    	int first = 0;
    	int last = data.size() - 1;
    	
    	int firstKIndex = GetFirstK(data, 0, last, k);
    	if(firstKIndex == -1)
    		return 0;
    	int lastKIndex = GetLastK(data, 0, last, k);
    	
    	return lastKIndex - firstKIndex + 1;
    }
    
    int GetFirstK(vector<int> &arr, int first, int last, int k)
    {
    	while(first <= last)
    	{
    		int mid = (first + last) / 2;
    		if(arr[mid] > k)
    		{
    			last = mid - 1;
    		}
    		else if(arr[mid] < k)
    		{
    			first = mid + 1;
    		}
    		else
    		{
    			if(mid == 0 || arr[mid - 1] != k)
    			{
    				return mid;
    			}
    			else
    			{
    				last = mid - 1;
    			}
    		}//else
    	}//while
    	
    	return -1;
    }
    
    int GetLastK(vector<int> &arr, int first, int last, int k)
    {
    	while(first <= last)
    	{
    		int mid = (first + last) / 2;
    		if(arr[mid] > k)
    		{
    			last = mid - 1;
    		}
    		else if(arr[mid] < k)
    		{
    			first = mid + 1;
    		}
    		else
    		{
    			if(mid == last || arr[mid + 1] != k)
    			{
    				return mid;
    			}
    			else
    			{
    				first = mid + 1;
    			}
    		}//else
    	}//while
    	
    	return -1;
    }
    

    在没有查找到k的时候,注意要返回一个标志-1,表示查找未成功。

  • 相关阅读:
    caffe源码整个训练过程
    设计模式--工厂模式 caffe_layer注册
    【Oracle】跟踪文件目录(User_Dump_Dest)生成脚本(11g/9i).txt
    【Oracle】修改参数的同时添加注释
    【Oracle】重置参数
    【Oracle】SCOPE=MEMORY|SPFILE|BOTH
    【Oracle】解锁用户
    【Oracle】开、关、删归档日志(archivelog)
    【Oracle】Rman简介
    【Oracle】非RMAN恢复数据文件、控制文件
  • 原文地址:https://www.cnblogs.com/stemon/p/4778544.html
Copyright © 2011-2022 走看看