C语言找出数组中的特定元素的算法解析_C 语言

     问题描述:一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
      思路:如果能用两个辅助数组,那么相对来说简单一点,可定义数组Min和数组Max,其中Min[i]表示自a[i]之后的最小值(包括a[i]),Max[i]表示自a[i]之前元素的最大值。有了这两个辅助数组后,对于a[i],如果它大于Max[i-1]并且小于Min[i+1],那么就符合要求。
      但是题目要求是只用一个额外数组,其实Max数组可以省去,完全可以边判断边计算,这是因为Max[i]是自左往右计算的,而判断时也是自左往右,两个过程正好可以合起来。只需用一个变量Max保存一下当前的最大值即可。下面给出两种方法的代码实现。
      参考代码:

//函数功能 : 找元素
//函数参数 : pArray指向数组,len为数组的元素个数
//返回值 : 无
void FindElements_Solution1(int *pArray, int len)
{
  if(pArray == NULL || len <= 0 )
    return ; 

  int *pMin = new int[len];
  int *pMax = new int[len];
  int i; 

  pMax[0] = pArray[0];
  for(i = 1; i < len; i++)    //计算自i往前最大值的辅助数组
    pMax[i] = (pMax[i-1] >= pArray[i])? pMax[i-1]: pArray[i];
  pMin[len-1] = pArray[len-1];
  for(i = len - 2; i >= 0; i--) //计算自i开始最小值的辅助数组
    pMin[i] = (pMin[i+1] <= pArray[i])? pMin[i+1]: pArray[i]; 

  if(pArray[0] <= pMin[0])   //检查第1个元素是否满足条件
    cout<<pArray[0]<<' ';
  for(i = 1; i < len - 1; i++)
  {
    if(pArray[i] >= pMax[i-1] && pArray[i] <=pMin[i+1]) //满足这个关系式的元素符合要求
      cout<<pArray[i]<<' ';
  }
  if(pArray[len-1] >= pMax[len-1]) //检查第len个元素是否满足条件
    cout<<pArray[i];
  cout<<endl; 

  delete [] pMin;
  delete [] pMax;
  pMin = pMax = NULL;
} 
void FindElements_Solution2(int *pArray, int len)
{
  if(pArray == NULL || len <= 0 )
    return ; 

  int *pMin = new int[len];
  int Max;
  int i; 

  Max = pArray[0];
  pMin[len-1] = pArray[len-1];
  for(i = len - 2; i >= 0; i--) //计算自i开始最小值的辅助数组
    pMin[i] = (pMin[i+1] <= pArray[i])? pMin[i+1]: pArray[i]; 

  if(pArray[0] <= pMin[0])   //检查第1个元素是否满足条件
    cout<<pArray[0]<<' '; 

  for(i = 1; i < len - 1; i++)
  {
    if(pArray[i] >= Max && pArray[i] <=pMin[i+1]) //满足这个关系式的元素符合要求
      cout<<pArray[i]<<' ';
    Max = (Max < pArray[i])? pArray[i]: Max; //更新当前最大值
  }
  if(pArray[len-1] >= Max) //检查第len个元素是否满足条件
    cout<<pArray[i];
  cout<<endl; 

  delete [] pMin;
  pMin = NULL;
} 

找出数组中两个只出现一次的数字(数组)
 问题描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
     思路:如果只有一个数字只出现一次,而其他都出现两次,则直接将所有数字做一次异或运算即可,因为相等的数字异或一下结果为0。如果有两个数字只出现一次,而其他数字出现了两次。该怎么办呢?《编程之美》一书提供了一种方法,即先将所有数字做一次异或运算,得到一个数字,然后以该数字的某非0位作为过滤位,将数组分成两个部分,此时只出现一次的数字会被分到不同的部分。现在问题就转为只出现一次的情况,对每部分分别做异或运算即可。
     参考代码:

//函数功能 : 找出数组中两个只出现一次的数字
//函数参数 : arr为源数组,len为数组元素个数,result用来存放结果
//返回值 :  无
void FindIsolateTwo(int *arr, int len, int *result)
{
  int i, all = 0, flag = 1; 

  for(i = 0; i < len ; i++) //所有数异或
    all ^= arr[i]; 

  while(!(all&flag)) //寻找过滤位
    flag <<= 1; 

  result[0] = result[1] = 0;
  for(i = 0; i < len; i++) //利用过滤位区分
  {
    if(flag&arr[i])
      result[0] ^= arr[i];
    else
      result[1] ^= arr[i];
  }
}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c语言
, 算法
数组
c语言找出数组最大值、c语言找出数组最小值、c语言数组排序算法、c语言数组右移算法、c语言找出最小值,以便于您获取更多的相关知识。

时间: 2024-11-10 07:10:56

C语言找出数组中的特定元素的算法解析_C 语言的相关文章

用java打印出数组中不同的元素,比如int[] a=new[]{2,4,5,6,3}和int[] b=new[]{1,4,8,6,9}哪位大侠能帮我!急!

问题描述 用java打印出数组中不同的元素,比如int[]a=new[]{2,4,5,6,3}和int[]b=new[]{1,4,8,6,9}/*结果输出1,8,9**/ 解决方案 解决方案二:publicclassTest{publicstaticvoidmain(String[]args){intnumA[]={2,4,5,6,3};intnumB[]={1,4,8,6,9};LinkedList<Integer>difNumList=newLinkedList<Integer>

找出数组中出现次数最多的数字

package cc; //找出数组{ 3, 4, 1, 5, 3, 1, 4, 5, 4, 3 }中出现次数最多的数字 //1 建立一个新数组,长度与原数组一致,然后将每个数字出现的次数存入此数组 //2 找出此数组中的最大值,尤其关注的是此最大值的下标 public class ArrayCount { public static void main(String[] args) { int test[] = new int[] { 1, 2, 3, 2, 3, 3 }; Arr arr =

PHP删除数组中的特定元素的代码_php技巧

比如下面的程序: 复制代码 代码如下: <?php $arr = array('apple','banana','cat','dog'); unset($arr[2]); print_r($arr); ?> 程序运行结果: 复制代码 代码如下: Array ( [0] => apple [1] => banana [3] => dog ) 但是这种方法的最大缺点是没有重建数组索引,就是说,数组的第三个元素没了. 经过查资料后,原来PHP提供了这个功能,只不过很间接.这个函数是

JavaScript实现找出数组中最长的连续数字序列_javascript技巧

原始题目: 给定一个无序的整数序列, 找最长的连续数字序列. 例如: 给定[100, 4, 200, 1, 3, 2], 最长的连续数字序列是[1, 2, 3, 4]. 小菜给出的解法: function maxSequence(array,step){ var _array = array.slice(), //clone array _step = 1, _arrayTemp = [], i = 0; var parseLogic = { //result container parseRe

C语言输出旋转后数组中的最小数元素的算法原理与实例_C 语言

  问题描述:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个排好序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1.      思路:这道题最直观的解法并不难.从头到尾遍历数组一次,就能找出最小的元素,时间复杂度显然是O(n).但这个思路没有利用输入数组的特性.既然有时间复杂度更小的算法,我们容易想到二分查找,因为它的时间复杂度为O(logn).这个问题是否可以运用二分查找呢

C语言中压缩字符串的简单算法小结_C 语言

应用中,经常需要将字符串压缩成一个整数,即字符串散列.比如下面这些问题: (1)搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节.请找出最热门的10个检索串. (2)有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M.返回频数最高的100个词. (3)有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复.要求你按照query的频度排序. (4)给定a.b两个文件

C/C++中可变参数的用法详细解析_C 语言

可变参数即表示参数个数可以变化,可多可少,也表示参数的类型也可以变化,可以是int,double还可以是char*,类,结构体等等.可变参数是实现printf(),sprintf()等函数的关键之处,也可以用可变参数来对任意数量的数据进行求和,求平均值带来方便(不然就用数组或每种写个重载).在C#中有专门的关键字parame,但在C,C++并没有类似的语法,不过幸好提供这方面的处理函数,本文将重点介绍如何使用这些函数. 第一步 可变参数表示用三个点-来表示,查看printf()函数和scanf(

C++中的friend友元函数详细解析_C 语言

友元函数是可以直接访问类的私有成员的非成员函数.它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend. 我们已知道类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性.另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运

C++中函数模板的用法详细解析_C 语言

定义 我们知道函数的重载可以实现一个函数名多用,将功能相同或者类似函数用同一个名来定义.这样可以简化函数的调用形式,但是程序中,仍然需要分别定义每一个函数. C++提供的函数模板可以更加简化这个过程. 所谓函数模板实际上是建立一个通用函数,其涵涵素类型额形参类型不具体指定,用一个虚拟的类型来代表,这个通用函数就称为函数模板. 凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需要在模板中定义一次即可.在调用函数时,系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能