也谈阿里巴巴面试题_身高排队问题

论坛 期权论坛 脚本     
已经匿名di用户   2022-7-2 21:51   2778   0

首先申明,我没有去阿里巴巴面试这个题目的,我是看到坛子里有人贴出问题的。我想如果是我去面试,我该怎么解决,如何去分析这个问题,这个问题背后隐藏的是什么哪类问题,花了一个晚上终于把它给弄出来了,不足之处大家给意见。

题目是这样的:12个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?

初看这个问题,如果是应试,还真有点摸不着头脑,但是静心想想,还是有规律的,一般面试题目都是一些经典的算法问题,只是常常将问题以某种看似日常化,生活的题目来叙述罢了。

首先把问题抽象,题目变成:给定一组整数(当然可以是整数,浮点数等,这里姑且当成整数处理,道理是一样的),这组整数中每个数值大小不一样,把这组整数分成两组,每组按照从小到大排列,要求一组每个成员数值比对应位置上的另外一组的成员数值小。

再进一步分解抽象:就是给定一组整数,从这整数中找X个整数出来,使得这X个数之和不大于给定整数数组之和的一半,如果这个一半的情况找到了,另外一半基本确定,因此,现在题目转化成从给定数组中找一个X个数,使得X个数之和小于给定数组之和的一半。

既然问题抽象了,那么现在来设计算法,一个最简单的算法就是穷举,人脑简直是太有限了,让计算机穷举去贝,这里采用遍历整个数组,即确定一个首元素后采用 栈来确定这个栈里面的元素是否符合上文中X个数的情况,如果符合就记录下来,如果不符合就进入下一步选择。具体算法是:
(1)先对给定数组Q排序,按照从小到大的顺序排列。
(2)然后循环这个数组(其时排序后循环一半就可以了,理由是找小的一半数组H,最小的元素肯定小于1/2长度的那个元素),把这个循环中的整数A1加入一个栈S,然后从给定数组Q中找比栈顶元素次大的一个元素最为下一个栈顶元素入栈,循环入栈操作。
(3)符合情况的记录:如果这个栈S的元素长度达到给定数组Q元素长度的一半时,就要判断这个栈S元素之和是否小于Q数组之和的一半,如果符合就记录这个 栈S的所有元素,并弹出栈顶元素Top,从Q数组中找下一个入栈元素,条件时这个入栈元素要比这个出栈元素Top大
(4)不符合半组H的情况:当栈S元素长度等于Q数组长度一半时,并且此时出栈元素是最后一个了(排序后最大的元素),那么就要出栈两个元素;当栈S元素长度等于Q数组长度一半时,并且此时栈S元素之和已大于给定数组Q之和的一半了,也要出栈两个元素;
(5)退出循环情况:当栈S只有小于等于一个元素了,且下一个元素为空,那么退出当前循环;当栈S小于等于两个元素长度,且下一个元素为数组Q最后一个元素时,那么退出当前循环;当栈S大于两个元素长度,且下一个元素为数组Q最后一个元素时,那么要出栈两个元素。
本人采用java语言实现了这个算法过程,可以任意定义数组大小,最后打印出来这个排列组合,具体程序如下:

Java代码 收藏代码
  1. package com.fruitking.test;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import java.util.Stack;
  6. /**
  7. * 给定一个整数列表(每个数大小都不一样),分成两队,
  8. * 每对按照高矮排列,且左边一对比右边一对对应位置上的值要小
  9. * @author XuGuo
  10. * @since 2009-10-27
  11. */
  12. public class HalfOfQueue {
  13. private List<Integer> queueList; //存储整个编队的人的身高数据列表
  14. private Stack<Integer> halfStack = new Stack<Integer>(); //遍历时候临时使用的栈
  15. private List<List<Integer>> halfResultList = new ArrayList<List<Integer>>(); //用于临时存储半个队列
  16. private List<List<Pair>> resultList = new ArrayList<List<Pair>>(); //用于存储结果排序好的符合要求的队列
  17. private int sum = 0 ; //整个编队的总大小
  18. private Integer lastMember; //排序后最大的元素
  19. public HalfOfQueue(List<Integer> queueList){
  20. this .queueList = this .sortQueueList(queueList);
  21. this .sumOfQueueList();
  22. if (queueList!= null &&queueList.size()>= 2 ){
  23. this .lastMember = queueList.get(queueList.size()- 1 );
  24. }
  25. }
  26. /**
  27. * 打印总过有多少组合,并且组合是哪些
  28. */
  29. public List<List<Pair>> getResultPairList(){
  30. return this .resultList;
  31. }
  32. /**
  33. * 查找和结果整理
  34. */
  35. public void run(){
  36. this .halfQueue();
  37. this .handlePairQueue();
  38. }
  39. /**
  40. * 匹配成对
  41. */
  42. private void handlePairQueue(){
  43. if (halfResultList!= null &&!halfResultList.isEmpty()){
  44. for ( int i= 0 ;i<halfResultList.size();i++){
  45. List<Integer> tempOneList = halfResultList.get(i);
  46. List<Integer> tempOtherList = new ArrayList<Integer>();
  47. int queueSize = this .queueList.size();
  48. if (tempOneList!= null &&!tempOneList.isEmpty()){
  49. Integer tempMember = null ;
  50. for ( int k= 0 ;k<queueSize;k++){
  51. tempMember = queueList.get(k);
  52. if (!tempOneList.contains(tempMember)){
  53. tempOtherList.add(tempMember);
  54. }
  55. }
  56. tempOtherList = this .sortQueueList(tempOtherList);
  57. }
  58. List<Pair> pairList = new ArrayList<Pair>();
  59. for ( int k= 0 ;k<tempOneList.size();k++){
  60. Pair pair = new Pair(tempOneList.get(k),tempOtherList.get(k));
  61. if (pair.isCorrectPair()){
  62. pairList.add(pair);
  63. }
  64. }
  65. if (pairList.size()== this .queueList.size()/ 2 ){
  66. this .resultList.add(pairList);
  67. }
  68. }
  69. }
  70. }
  71. /**
  72. * 半块队列的穷举
  73. */
  74. private void halfQueue(){
  75. for ( int i= 0 ;i<queueList.size()/ 2 ;i++){
  76. if (queueList.size()< 2 ){
  77. return ;
  78. }
  79. halfStack.clear();
  80. halfStack.push(queueList.get(i));
  81. Integer inNextMember = halfStack.peek();
  82. Integer topStackMember = null ;
  83. while ( true ){
  84. if (halfStack.size()<(queueList.size()/ 2 )){
  85. inNextMember = getNextMember(inNextMember);
  86. if (inNextMember!= null ){
  87. halfStack.push(inNextMember);
  88. }else {
  89. if (halfStack.size()<= 1 ){
  90. break ; //退出条件
  91. }else {
  92. halfStack.pop();//退出最后一个元素
  93. inNextMember = halfStack.pop();//退出到数第二个元素
  94. continue ;
  95. }
  96. }
  97. if (halfStack.size()==(queueList.size()/ 2 )){
  98. if ( this .isHalfOfSumQueueList()){
  99. List<Integer> tempList = new ArrayList<Integer>();
  100. tempList.addAll(halfStack);
  101. halfResultList.add(tempList);
  102. topStackMember = halfStack.pop();//当栈满时退出最后一个栈元素
  103. if (topStackMember.intValue()== this .lastMember.intValue()){
  104. //最后一个元素了
  105. inNextMember = halfStack.pop();//当栈差一个元素满时退出最后一个元素
  106. }
  107. }else {
  108. halfStack.pop();//退出最后一个元素(这个元素的加入已经满足此栈所有元素不符合业务逻辑的情况了)
  109. inNextMember = halfStack.pop();//退出到数第二个元素(即使后面还有元素已经不满足业务逻辑了)
  110. }
  111. }else if (inNextMember.intValue()== this .lastMember.intValue()){
  112. if (halfStack.size()<= 2 ){ //第一个元素和最后一个元素了也就要退出
  113. break ; //退出条件
  114. }else {
  115. halfStack.pop();//退出最后一个元素(这个元素一定是编队中最大的元素)
  116. inNextMember = halfStack.pop();//退出到数第二个元素
  117. }
  118. }
  119. }
  120. }
  121. }
  122. }
  123. /**
  124. * 是否是编队值的一半的最大值
  125. * @return
  126. */
  127. private boolean isHalfOfSumQueueList(){
  128. int sumOfHalf = 0 ;
  129. if (halfStack!= null &&!halfStack.isEmpty()){
  130. Iterator<Integer> halfStackIt = halfStack.iterator();
  131. while (halfStackIt.hasNext()){
  132. sumOfHalf = sumOfHalf + halfStackIt.next().intValue();
  133. }
  134. if (sumOfHalf<=( this .sum/ 2 -queueList.size()/ 4 )){
  135. return true ;
  136. }
  137. }
  138. return false ;
  139. }
  140. /**
  141. * 获得比当前元素大的元素,已经对成员列表排序了
  142. * 如果当前为空就返回最小的那个元素,如果当前元素最大,就返回最大的那个元素
  143. * @return
  144. */
  145. private Integer getNextMember(Integer currentMember){
  146. Integer nextMember = null ;
  147. if (queueList!= null &&!queueList.isEmpty()){
  148. if (currentMember!= null &&currentMember.intValue()== this .lastMember.intValue()){
  149. return null ;
  150. }
  151. Iterator<Integer> memberIt = queueList.iterator();
  152. while (memberIt.hasNext()){
  153. nextMember = memberIt.next();
  154. if (currentMember!= null ){
  155. if (nextMember.intValue()>currentMember.intValue()){
  156. break ;
  157. }
  158. }else {
  159. break ;
  160. }
  161. }
  162. }
  163. return nextMember;
  164. }
  165. /**
  166. * 求队列和
  167. */
  168. private void sumOfQueueList(){
  169. if (queueList!= null &&!queueList.isEmpty()){
  170. for ( int k= 0 ;k<queueList.size();k++){
  171. sum = sum + queueList.get(k).intValue();
  172. }
  173. }
  174. }
  175. /**
  176. * 对编队按照从小到大排序
  177. * @param queueList
  178. * @return
  179. */
  180. private List<Integer> sortQueueList(List<Integer> srcQueueList){
  181. List<Integer> destQueueList = new ArrayList<Integer>();
  182. if (srcQueueList!= null &&!srcQueueList.isEmpty()){
  183. List<Integer> tempList = new ArrayList<Integer>();
  184. tempList.addAll(srcQueueList);
  185. Iterator<Integer> outIt = tempList.iterator();
  186. while (outIt.hasNext()){
  187. Integer nextMember = null ;
  188. Integer tempMember = null ;
  189. Iterator<Integer> inIt = tempList.iterator();
  190. while (inIt.hasNext()){
  191. tempMember = inIt.next();
  192. if (nextMember== null ){
  193. nextMember = tempMember;
  194. }
  195. if (nextMember.intValue()>tempMember.intValue()){
  196. nextMember = tempMember;
  197. }
  198. }
  199. if (nextMember!= null ){
  200. destQueueList.add(nextMember);
  201. tempList.remove(nextMember);
  202. outIt = tempList.iterator();
  203. }
  204. }
  205. }
  206. return destQueueList;
  207. }
  208. }

Java代码 收藏代码
  1. package com.fruitking.test;
  2. /**
  3. * 数据封装而已,不想用太多的数组这样的单个东西
  4. * @author XuGuo
  5. * @since 2009-10-27
  6. */
  7. public class Pair {
  8. private Integer left;
  9. private Integer right;
  10. public Pair(Integer left,Integer right){
  11. this .left = left;
  12. this .right = right;
  13. }
  14. /**
  15. * 判断这对是否是正确的组合(即左边这个元素是否小于右边这个元素)
  16. * @return
  17. */
  18. public boolean isCorrectPair(){
  19. if (left!= null &&right!= null &&left.intValue()<right.intValue()){
  20. return true ;
  21. }else {
  22. return false ;
  23. }
  24. }
  25. public int getLeft() {
  26. return left;
  27. }
  28. public void setLeft( int left) {
  29. this .left = left;
  30. }
  31. public int getRight() {
  32. return right;
  33. }
  34. public void setRight( int right) {
  35. this .right = right;
  36. }
  37. }

Java代码 收藏代码
  1. package com.fruitking.test;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * @author XuGuo
  6. * @since 2009-10-27
  7. */
  8. public class Test10 {
  9. /**
  10. * 12个高矮不同的人,排成两排,每排必须是从矮到高排列,
  11. * 而且第二排比对应的第一排的人高,问排列方式有多少种?
  12. */
  13. public static void main(String[] args) {
  14. List<Integer> list = new ArrayList<Integer>();
  15. list.add(new Integer( 2 ));list.add( new Integer( 4 ));
  16. list.add(new Integer( 1 ));list.add( new Integer( 3 ));
  17. list.add(new Integer( 5 ));list.add( new Integer( 6 ));
  18. list.add(new Integer( 7 ));list.add( new Integer( 8 ));
  19. list.add(new Integer( 9 ));list.add( new Integer( 11 ));
  20. list.add(new Integer( 10 ));list.add( new Integer( 12 ));
  21. HalfOfQueue test1 = new HalfOfQueue(list);
  22. test1.run();
  23. List<List<Pair>> resultList = test1.getResultPairList();
  24. /**
  25. * 打印总过有多少组合,并且组合是哪些
  26. */
  27. System.out.println();
  28. System.out.println("---总共有" +resultList.size()+ "个组合---" );
  29. for ( int i= 0 ;i<resultList.size();i++){
  30. List<Pair> tempList = resultList.get(i);
  31. if (tempList!= null &&!tempList.isEmpty()){
  32. System.out.println("--------------------" );
  33. for ( int k= 0 ;k<tempList.size();k++){
  34. System.out.print(tempList.get(k).getLeft()+" " );
  35. }
  36. System.out.println();
  37. for ( int k= 0 ;k<tempList.size();k++){
  38. System.out.print(tempList.get(k).getRight()+" " );
  39. }
  40. System.out.println();
  41. }
  42. }
  43. }
  44. }


运行结果:


---总共有132个组合---
--------------------
1 2 3 4 5 6
7 8 9 10 11 12
--------------------
1 2 3 4 5 7
6 8 9 10 11 12
--------------------
1 2 3 4 5 8
6 7 9 10 11 12
--------------------
1 2 3 4 5 9
6 7 8 10 11 12
--------------------
1 2 3 4 5 10
6 7 8 9 11 12
--------------------
1 2 3 4 5 11
6 7 8 9 10 12
--------------------
1 2 3 4 6 7
5 8 9 10 11 12
--------------------
1 2 3 4 6 8
5 7 9 10 11 12
--------------------
1 2 3 4 6 9
5 7 8 10 11 12
--------------------
1 2 3 4 6 10
5 7 8 9 11 12
--------------------
1 2 3 4 6 11
5 7 8 9 10 12
--------------------
1 2 3 4 7 8
5 6 9 10 11 12
--------------------
1 2 3 4 7 9
5 6 8 10 11 12
--------------------
1 2 3 4 7 10
5 6 8 9 11 12
--------------------
1 2 3 4 7 11
5 6 8 9 10 12
--------------------
1 2 3 4 8 9
5 6 7 10 11 12
--------------------
1 2 3 4 8 10
5 6 7 9 11 12
--------------------
1 2 3 4 8 11
5 6 7 9 10 12
--------------------
1 2 3 4 9 10
5 6 7 8 11 12
--------------------
1 2 3 4 9 11
5 6 7 8 10 12
--------------------
1 2 3 5 6 7
4 8 9 10 11 12
--------------------
1 2 3 5 6 8
4 7 9 10 11 12
--------------------
1 2 3 5 6 9
4 7 8 10 11 12
--------------------
1 2 3 5 6 10
4 7 8 9 11 12
--------------------
1 2 3 5 6 11
4 7 8 9 10 12
--------------------
1 2 3 5 7 8
4 6 9 10 11 12
--------------------
1 2 3 5 7 9
4 6 8 10 11 12
--------------------
1 2 3 5 7 10
4 6 8 9 11 12
--------------------
1 2 3 5 7 11
4 6 8 9 10 12
--------------------
1 2 3 5 8 9
4 6 7 10 11 12
--------------------
1 2 3 5 8 10
4 6 7 9 11 12
--------------------
1 2 3 5 8 11
4 6 7 9 10 12
--------------------
1 2 3 5 9 10
4 6 7 8 11 12
--------------------
1 2 3 5 9 11
4 6 7 8 10 12
--------------------
1 2 3 6 7 8
4 5 9 10 11 12
--------------------
1 2 3 6 7 9
4 5 8 10 11 12
--------------------
1 2 3 6 7 10
4 5 8 9 11 12
--------------------
1 2 3 6 7 11
4 5 8 9 10 12
--------------------
1 2 3 6 8 9
4 5 7 10 11 12
--------------------
1 2 3 6 8 10
4 5 7 9 11 12
--------------------
1 2 3 6 8 11
4 5 7 9 10 12
--------------------
1 2 3 6 9 10
4 5 7 8 11 12
--------------------
1 2 3 6 9 11
4 5 7 8 10 12
--------------------
1 2 3 7 8 9
4 5 6 10 11 12
--------------------
1 2 3 7 8 10
4 5 6 9 11 12
--------------------
1 2 3 7 8 11
4 5 6 9 10 12
--------------------
1 2 3 7 9 10
4 5 6 8 11 12
--------------------
1 2 3 7 9 11
4 5 6 8 10 12
--------------------
1 2 4 5 6 7
3 8 9 10 11 12
--------------------
1 2 4 5 6 8
3 7 9 10 11 12
--------------------
1 2 4 5 6 9
3 7 8 10 11 12
--------------------
1 2 4 5 6 10
3 7 8 9 11 12
--------------------
1 2 4 5 6 11
3 7 8 9 10 12
--------------------
1 2 4 5 7 8
3 6 9 10 11 12
--------------------
1 2 4 5 7 9
3 6 8 10 11 12
--------------------
1 2 4 5 7 10
3 6 8 9 11 12
--------------------
1 2 4 5 7 11
3 6 8 9 10 12
--------------------
1 2 4 5 8 9
3 6 7 10 11 12
--------------------
1 2 4 5 8 10
3 6 7 9 11 12
--------------------
1 2 4 5 8 11
3 6 7 9 10 12
--------------------
1 2 4 5 9 10
3 6 7 8 11 12
--------------------
1 2 4 5 9 11
3 6 7 8 10 12
--------------------
1 2 4 6 7 8
3 5 9 10 11 12
--------------------
1 2 4 6 7 9
3 5 8 10 11 12
--------------------
1 2 4 6 7 10
3 5 8 9 11 12
--------------------
1 2 4 6 7 11
3 5 8 9 10 12
--------------------
1 2 4 6 8 9
3 5 7 10 11 12
--------------------
1 2 4 6 8 10
3 5 7 9 11 12
--------------------
1 2 4 6 8 11
3 5 7 9 10 12
--------------------
1 2 4 6 9 10
3 5 7 8 11 12
--------------------
1 2 4 6 9 11
3 5 7 8 10 12
--------------------
1 2 4 7 8 9
3 5 6 10 11 12
--------------------
1 2 4 7 8 10
3 5 6 9 11 12
--------------------
1 2 4 7 8 11
3 5 6 9 10 12
--------------------
1 2 4 7 9 10
3 5 6 8 11 12
--------------------
1 2 4 7 9 11
3 5 6 8 10 12
--------------------
1 2 5 6 7 8
3 4 9 10 11 12
--------------------
1 2 5 6 7 9
3 4 8 10 11 12
--------------------
1 2 5 6 7 10
3 4 8 9 11 12
--------------------
1 2 5 6 7 11
3 4 8 9 10 12
--------------------
1 2 5 6 8 9
3 4 7 10 11 12
--------------------
1 2 5 6 8 10
3 4 7 9 11 12
--------------------
1 2 5 6 8 11
3 4 7 9 10 12
--------------------
1 2 5 6 9 10
3 4 7 8 11 12
--------------------
1 2 5 6 9 11
3 4 7 8 10 12
--------------------
1 2 5 7 8 9
3 4 6 10 11 12
--------------------
1 2 5 7 8 10
3 4 6 9 11 12
--------------------
1 2 5 7 8 11
3 4 6 9 10 12
--------------------
1 2 5 7 9 10
3 4 6 8 11 12
--------------------
1 2 5 7 9 11
3 4 6 8 10 12
--------------------
1 3 4 5 6 7
2 8 9 10 11 12
--------------------
1 3 4 5 6 8
2 7 9 10 11 12
--------------------
1 3 4 5 6 9
2 7 8 10 11 12
--------------------
1 3 4 5 6 10
2 7 8 9 11 12
--------------------
1 3 4 5 6 11
2 7 8 9 10 12
--------------------
1 3 4 5 7 8
2 6 9 10 11 12
--------------------
1 3 4 5 7 9
2 6 8 10 11 12
--------------------
1 3 4 5 7 10
2 6 8 9 11 12
--------------------
1 3 4 5 7 11
2 6 8 9 10 12
--------------------
1 3 4 5 8 9
2 6 7 10 11 12
--------------------
1 3 4 5 8 10
2 6 7 9 11 12
--------------------
1 3 4 5 8 11
2 6 7 9 10 12
--------------------
1 3 4 5 9 10
2 6 7 8 11 12
--------------------
1 3 4 5 9 11
2 6 7 8 10 12
--------------------
1 3 4 6 7 8
2 5 9 10 11 12
--------------------
1 3 4 6 7 9
2 5 8 10 11 12
--------------------
1 3 4 6 7 10
2 5 8 9 11 12
--------------------
1 3 4 6 7 11
2 5 8 9 10 12
--------------------
1 3 4 6 8 9
2 5 7 10 11 12
--------------------
1 3 4 6 8 10
2 5 7 9 11 12
--------------------
1 3 4 6 8 11
2 5 7 9 10 12
--------------------
1 3 4 6 9 10
2 5 7 8 11 12
--------------------
1 3 4 6 9 11
2 5 7 8 10 12
--------------------
1 3 4 7 8 9
2 5 6 10 11 12
--------------------
1 3 4 7 8 10
2 5 6 9 11 12
--------------------
1 3 4 7 8 11
2 5 6 9 10 12
--------------------
1 3 4 7 9 10
2 5 6 8 11 12
--------------------
1 3 4 7 9 11
2 5 6 8 10 12
--------------------
1 3 5 6 7 8
2 4 9 10 11 12
--------------------
1 3 5 6 7 9
2 4 8 10 11 12
--------------------
1 3 5 6 7 10
2 4 8 9 11 12
--------------------
1 3 5 6 7 11
2 4 8 9 10 12
--------------------
1 3 5 6 8 9
2 4 7 10 11 12
--------------------
1 3 5 6 8 10
2 4 7 9 11 12
--------------------
1 3 5 6 8 11
2 4 7 9 10 12
--------------------
1 3 5 6 9 10
2 4 7 8 11 12
--------------------
1 3 5 6 9 11
2 4 7 8 10 12
--------------------
1 3 5 7 8 9
2 4 6 10 11 12
--------------------
1 3 5 7 8 10
2 4 6 9 11 12
--------------------
1 3 5 7 8 11
2 4 6 9 10 12
--------------------
1 3 5 7 9 10
2 4 6 8 11 12
--------------------
1 3 5 7 9 11
2 4 6 8 10 12

http://fruitking.iteye.com/blog/505037

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP