当前位置:   article > 正文

每日一题(61) - 找出左边比它小,右边比它大的数_给出一个元素无序的数组,求出一个数,使得其左边的数都小于它,右边的数都大于等于

给出一个元素无序的数组,求出一个数,使得其左边的数都小于它,右边的数都大于等于

题目来自网络

题目:

给出一个元素无序的数组,求出一个数,使得其左边的数都小于它,右边的数都大于等于它。

举例:1,2,3,1,2,0,5,6,返回下标6(数字为5)。

思路(1):

朴素算法,对于每一个数,都检测它的左边和右边是否满足题意。

时间复杂度为O(n^2)

思路(2)

使用变量求解:

(1)目前找到符合题意的候选值,nCandid

(2)目前已遍历数组的最大值,nMax:为了选下一次的候选值

(3)目前的候选值是否有效,bIsExist:检测是否需要重新选择候选值

思路:如果候选值有效,可以继续遍历下面的数据

如果候选值小于目前的值,则该候选失效。之后遍历元素时,就要重新选择候选值

选择候选值时,对于某一个元素,如果该元素比之前遍历过元素的最大值还要大nMax,则该元素就为候选。

复杂度:遍历一遍数组即可,时间:O(n),空间O(1)

代码

  1. #include <iostream>
  2. #include <assert.h>
  3. #include <list>
  4. using namespace std;
  5. int FindNum(int nArr[],int nLen)
  6. {
  7. assert(nArr && nLen > 0);
  8. int nPos = 0;
  9. int nCandid = nArr[0];
  10. int nMax = nArr[0];
  11. bool bIsExist = true;
  12. for (int i = 1;i < nLen;i++)
  13. {
  14. if (bIsExist)//候选有效
  15. {
  16. if (nCandid > nArr[i])//候选失效
  17. {
  18. bIsExist = false;
  19. }
  20. else
  21. {
  22. nMax = nArr[i];
  23. }
  24. }
  25. else //候选失效
  26. {
  27. if (nArr[i] >= nMax)//重新找到候选
  28. {
  29. bIsExist = true;
  30. nCandid = nArr[i];
  31. nMax = nArr[i];
  32. nPos = i;
  33. }
  34. }
  35. }
  36. return bIsExist ? nPos : -1;
  37. }
  38. int main()
  39. {
  40. int nArr[8] = {1,2,3,1,2,0,5,6};
  41. int nPos = FindNum(nArr,8);
  42. if (nPos == -1)
  43. {
  44. cout<<"不存在!"<<endl;
  45. }
  46. else
  47. {
  48. cout<<nArr[nPos]<<endl;
  49. }
  50. // int nArr[7] = {7,7,7,7,7,7,7};
  51. // int nPos = FindNum(nArr,7);
  52. // if (nPos == -1)
  53. // {
  54. // cout<<"不存在!"<<endl;
  55. // }
  56. // else
  57. // {
  58. // cout<<nArr[nPos]<<endl;
  59. // }
  60. // int nArr[7] = {1,2,3,4,5,6,7};
  61. // int nPos = FindNum(nArr,7);
  62. // if (nPos == -1)
  63. // {
  64. // cout<<"不存在!"<<endl;
  65. // }
  66. // else
  67. // {
  68. // cout<<nArr[nPos]<<endl;
  69. // }
  70. // int nArr[7] = {7,6,5,4,3,2,1};
  71. // int nPos = FindNum(nArr,7);
  72. // if (nPos == -1)
  73. // {
  74. // cout<<"不存在!"<<endl;
  75. // }
  76. // else
  77. // {
  78. // cout<<nArr[nPos]<<endl;
  79. // }
  80. system("pause");
  81. return 1;
  82. }

题目二

题目:

给出一个元素无序的数组,求出使得其左边的数都小于它,右边的数都大于等于它的所有数字

举例:

(1)1,2,3,1,2,0,5,6 : 输出5,6

(2)1,2,3,1,2,0,5,5 : 输出5(第一个5)

(3)1,2,3,4,5,6,7 : 输出1,2,3,4,5,6,7 

思路:

使用一个数组nArrMin[i]来保存[i,nLen-1]区间内的最小值。

使用一个变量nMax保存区间[0,i-1]的最大值。

对于第i个数,如果它满足nArr[i]大于左边的最大数nMax 且 小于右边的最小数nArrMin[i],则该数即为所求。

复杂度:时间:O(n),空间O(n)

代码

  1. #include <iostream>
  2. #include <assert.h>
  3. #include <list>
  4. using namespace std;
  5. void FindNum(int nArr[],int nLen)
  6. {
  7. assert(nArr && nLen > 0);
  8. int nPos = 0;
  9. int nMax = -0x3f3f3f3f;
  10. int nArrMin[100];
  11. nArrMin[nLen - 1] = nArr[nLen - 1];
  12. //遍历一遍数组,记录区间[i,len-1]的最小值,并保存到数组nArr[i]中
  13. for (int i = nLen - 2;i >= 0;i--)
  14. {
  15. if (nArr[i] > nArrMin[i + 1])
  16. {
  17. nArrMin[i] = nArrMin[i + 1];
  18. }
  19. else
  20. {
  21. nArrMin[i] = nArr[i];
  22. }
  23. }
  24. //遍历一遍数组,求解满足题意的数
  25. for (int i = 0;i < nLen;i++)
  26. {
  27. if (nArr[i] > nMax)
  28. {
  29. if (nArr[i] <= nArrMin[i])
  30. {
  31. //nArr[i]比左边数的最大值还要大且比右边数的最小值还要小,则输出
  32. cout<<nArr[i]<<" ";
  33. }
  34. nMax = nArr[i];
  35. }
  36. }
  37. }
  38. int main()
  39. {
  40. int nArr[8] = {1,2,3,1,2,0,5,6};
  41. FindNum(nArr,8);//5 6
  42. // int nArr[7] = {1,2,3,4,5,6,7};
  43. // FindNum(nArr,7);//1,2,3,4,5,6,7}
  44. // int nArr[7] = {7,6,5,4,3,2,1};
  45. // FindNum(nArr,7);//不存在
  46. // int nArr[7] = {7,7,7,7,7,7,7};
  47. // FindNum(nArr,7);//7
  48. system("pause");
  49. return 1;
  50. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/227664
推荐阅读
相关标签
  

闽ICP备14008679号