如何排序数组中仅升序的奇数?

时间:2018-07-04 17:01:18

标签: c# arrays sorting

我只想排序奇数而不移动偶数。例如,如果我输入的是:

[5, 3, 2, 8, 1, 4]

预期结果是:

[1, 3, 2, 8, 5, 4]

我是C#的新手,我在互联网上遇到了一个使我感到困惑的挑战。我已经尝试了几个小时,我想在

中学习这个概念

挑战说明:

  

您有一组数字。您的任务是对升序的奇数进行排序,但偶数必须在其位置。零不是一个奇数,您不需要移动它。如果您有一个空数组,则需要将其返回。

到目前为止,这是我的代码,请放心,我正处于编程的开始阶段。

public static int[] SortArray(int[] array)
{
    var dict = new Dictionary<int, int>();
    var dict2 = new Dictionary<int, int>();

    for (int i = 0; i < array.Length; i++)
    {
        int j =0;
        if (array[i] % 2 != 0)
        {
            dict.Add(array[i], i+1);
        }
        else
        {
            dict2.Add(array[i], i+1);
        }
    }
    var result = dict.OrderBy(x => x.Key);
    Dictionary<int, int> resultDic = result.Union(dict2)
      .GroupBy(x => x.Key).ToDictionary(o => o.Key, o => o.Key);
}

public static void Main()
{
    SortArray(new int[] { 5, 3, 2, 8, 1, 4});
}

3 个答案:

答案 0 :(得分:3)

检查此代码。解释已添加为注释

public static int[] SortArray(int[] array)
{
    //temp variable for holding larger value for switching
    int temp = 0;

    for (int i = 0; i < array.Length; i++)
    {
        //If the value is 'even' continue with outer loop
        if(array[i] % 2 == 0)
           continue;

        //Inner loop to compare array values
        for(int j = (i + 1); j < array.Length; j++)
        {
            //If this value is not even do comparison
            if(array[j] % 2 != 0)
            {
                //If the left value is greater than the right value
                //swap them
                if(array[i] > array[j])
                {
                   temp = array[i];
                   array[i] = array[j];
                   array[j] = temp;
                }
            }
        }
    }

    return array;
}

public static void Main()
{
    SortArray(new int[] { 5, 3, 2, 8, 1, 4});
}

答案 1 :(得分:2)

您可以使用linq通过在开始之前为数字编制索引来完成此操作:

var nums = new[] { 5, 3, 2, 8, 1, 4 };
var indexedNums = nums.Select((num, idx) => new { num, idx }).ToList();

然后将这些索引数字排序为偶数和偶数:

var evens = indexedNums.Where(x => x.num % 2 == 0);
var odds = indexedNums.Where(x => x.num % 2 == 1);

按值对奇数(索引)进行排序:

var sortedOdds = odds.OrderBy(x => x.num); //sort the odd numbers by their value

将此序列与odds序列(按索引排序)压缩在一起,从sortedOdds取数字,从odds取索引

var reindexedOdds = sortedOdds.Zip(odds, (o1, o2) => new { o1.num, o2.idx });

......然后将这些reindexedOdds放入一个从上面索引为evens的序列中,按索引排序,然后选择数字。

var endSequence = evens.Concat(reindexedOdds).OrderBy(x => x.idx).Select(x => x.num);

答案 2 :(得分:0)

虽然其他解决方案在形式上是正确的,但大多数解决方案效率不高,具有public static int[] SortArray(int[] array) { var sortedOdds = new List<int>(array.Length); var oddsIndexes = new List<int>(array.Length); var newArray = new int[array.Length]; for(var i = 0; i < array.Length; i++) // O(n) { var value = array[i]; if(value % 2 == 1) { sortedOdds.Add(value); oddsIndexes.Add(i); } else { newArray[i] = value; } } sortedOdds.Sort(); // average complexity O(n log n) for(var j = 0; j < sortedOdds.Count; j++) // O(n) { var value = sortedOdds[j]; var index = oddsIndexes[j]; newArray[index] = value; } return newArray; } 的时间复杂度。

另一种(更节省时间的)方法应隐含使用两个列表:第一个将包含奇数索引,第二个将存储排序的奇数。

O(n log n)

这会将复杂性降低到平均Route::get('/api/send.php', function(){ echo 'Hi There'; }); 时间。