zoukankan      html  css  js  c++  java
  • 记一道面试题

    题目是这样的,已知一个整数数列(这里应该说的是正整数数列)和一个给定的sum值,从这个整数数列中,找出两个整数的和刚好等于sum值,将这个数列中所有这种可能的组合进行输出。

    例如:有一个整数数列{3,4,2,7,5,2,4},sum=6,

    那么这样的组合就有:

    第二项和第三项的和,即<2,3>;

    第二项和第六项的和,即<2,6>;

    第三项和第七项的和,即<3,7>;

    以此类推…

    当时我的解答是这样,比较笨哈:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication16
    {
    class Program
    {
    static void Main(string[] args)
    {
    int[] testArray = { 3, 4, 2, 7, 5, 2, 4 };
    Console.WriteLine(GetNumCombinations(testArray,6));
    }

    public static string GetNumCombinations(int[] arrayInt, int sum)
    {
    List<int> firstNums = new List<int>();
    List<int> secondNums = new List<int>();

    for (int i = 0; i < arrayInt.Length-1; i++)
    {
    for (int j = i+1; j < arrayInt.Length; j++)
    {
    if (arrayInt[i]+arrayInt[j]==sum)
    {
    firstNums.Add(i+1);
    secondNums.Add(j + 1);
    }
    }
    }

    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < firstNums.Count; i++)
    {
    sb.Append(String.Format("<{0},{1}>",firstNums[i],secondNums[i]));
    }

    return sb.ToString();
    }
    }
    }

    这里有两个问题,第一个问题就是采用List来保存配对的元素。List的内部顺序是不稳定的,也就是说,你先Add进去的元素并不一定会在后Add进去的元素前面,所以,有可能会造成配对的信息错误。(这个问题其实我没考证过,是那个面试官这么解释的,大致意思我猜想就是这样)所以应该自定义一个数据结构进行保存。

    还有一个问题就是算法的效率问题了,具体差在哪?一看就懂得哈!

    面试官给了我一个方案,先对数列进行一个从小到大的排序,找sum,和sum/2在数列中的位置,然后再循环查找。

    回来后总结了一下,我想他的大致意思应该是这样的:

    继续拿上面得例子演示,先将数列进行排序。

    2,2,3,4,4,5,7

    当然,顺序乱了,之前的序列值肯定也不对了,所以需要多增加一个数组来维护它的序列值,就假如它排序后的序列值如下:

    2,2,3,4,4,5,7

    3,6,1,2,7,5,4(这一行是序列值)

    然后找到sum和sum/2在该序列中的位置,sum=6,sum/2=3:

    2,2,3,(3),4,4,5,(6),7

    相信大部分人应该看出名堂了吧,想要两个数的和相加等于6,那么这两个数必定有一个小于3,另一个大于3,不可能有两个数都大于3的数相加小于等于6的,同理,也不可能有两个数都小于3的数相加大于等于6的。

    在取数据进行相加的时候,设一个变量x从最小值到中间值,一个变量y从最大值到中间值:

    →x                ←y

    2,2,3,(3),4,4,5,(6),7

    如果两数相加比sum大,那么最大值y肯定更小,如果两数相加比sum小,那么最小值x需要更大,直到x与y到中间值为止。

    代码重新整理如下(咱就不考虑排序的效率了哈,也没有很好的容错性,应该会有各种BUG哈,呵呵!)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication17
    {
    //保存配对信息
    struct NumCombin
    {
    public int x;
    public int y;

    public override string ToString()
    {
    return String.Format("<{0},{1}>", x, y);
    }
    }

    class Program
    {
    public static NumCombin[] GetNumCombinations(int[] arrayInt, int sum)
    {
    List<NumCombin> numCombinList = new List<NumCombin>();

    //创建一个数组维护排序顺序
    int[] arrayOrder = new int[arrayInt.Length];
    for (int i = 0; i < arrayOrder.Length; i++)
    {
    arrayOrder[i] = i + 1;
    }

    //一个简单的冒泡,进行从小到大的排序
    for (int i = 0; i < arrayInt.Length; i++)
    {
    bool isChange = false;

    for (int j = 0; j < arrayInt.Length-1-i; j++)
    {
    if (arrayInt[j]>arrayInt[j+1])
    {
    int temp = arrayInt[j];
    arrayInt[j] = arrayInt[j + 1];
    arrayInt[j + 1] = temp;

    temp = arrayOrder[j];
    arrayOrder[j] = arrayOrder[j + 1];
    arrayOrder[j + 1] = temp;

    isChange = true;
    }
    }

    if (!isChange)
    {
    break;
    }
    }

    int maxCount=-1, halfCount=-1;

    for (int i = 0; i < arrayInt.Length; i++)
    {
    if (arrayInt[i]>sum)
    {
    maxCount = i;
    break;
    }
    }

    if (maxCount==-1)
    {
    maxCount = arrayInt.Length;
    }

    for (int i = 0; i < arrayInt.Length; i++)
    {
    if (arrayInt[i]>sum/2)
    {
    halfCount = i;
    break;
    }
    }

    //如果这个数列最大的数都没有达到sum值的一半,
    //那么肯定不会存在两个数相加为sum的值
    if (halfCount==-1)
    {
    return null;
    }

    for (int i = 0; i < halfCount; i++)
    {
    for (int j = maxCount; j >= halfCount; j--)
    {
    if (arrayInt[i] + arrayInt[j] > sum)
    {
    maxCount--;

    }
    else if (arrayInt[i] + arrayInt[j] < sum)
    {
    break;
    }
    else
    {
    NumCombin numCombin = new NumCombin() { x = arrayOrder[i], y = arrayOrder[j] };
    numCombinList.Add(numCombin);
    }
    }
    }

    return numCombinList.ToArray();
    }

    static void Main(string[] args)
    {
    NumCombin[] test = GetNumCombinations(new int[] { 3, 4, 2, 7, 5, 2, 4 },6);

    foreach (var item in test)
    {
    Console.WriteLine(item);
    }

    }
    }
    }

    代码写得有点拙劣,望广大博友批评指导!希望有人能提出更好的方案哈!

  • 相关阅读:
    程序写法
    2011年C++再次给力
    WIN7+LINUX双系统
    随机洗牌算法
    Eclipse快捷键大全
    Android 编程规范
    android Context 上下文的几点解析
    消息模式Toast.makeText的几种常见用法
    Eclipse的优化
    用PULL解析器解析XML文件
  • 原文地址:https://www.cnblogs.com/heqichang/p/2374809.html
Copyright © 2011-2022 走看看