题目
自己的理解
#region 二分查找法
{
var info = new ErFen();
var r = new Random();
StringBuilder text = new StringBuilder();
//1、查找key下最大的值或等同于它的值
{
//设置一个有序数组
var arr = new int[] { 1, 3, 7, 10, 14, 18 };
var key = r.Next(arr[arr.Length - 1]);
foreach (var item in arr)
{
text.Append(item + ",");
}
Console.WriteLine($"数组:{text.Remove(text.Length - 1, 1).ToString()} 找key下最大的值或等同于它的值");
Console.WriteLine($"key:{key},value:{info.GetKeyLowMax(arr, key)}");
}
//2/3、给一个有重复元素的已排序数组,找出给定的元素key出现的次数,时间复杂度要求为logN
{
text.Clear();
var arr = new int[20];
for (int i = 0; i < arr.Length; i++)
{
arr[i] = r.Next(100);
}
Array.Sort(arr);
var key = arr[r.Next(arr.Length - 1)];
foreach (var item in arr)
{
text.Append(item + ",");
}
var model = info.GetKeyNum(arr, key);
Console.WriteLine($"数组:{text.Remove(text.Length - 1, 1).ToString()} 找出给定的元素key出现的次数的个数/第一次与最后一次下标");
Console.WriteLine($"key:{key},num:{model.End - model.Start + 1},第一次下标:{model.Start},最后一次下标:{model.End}");
}
//4、随意旋转后找到最小值所在
{
text.Clear();
var arr = new int[20];
var i = 0;
do
{
int value = r.Next(100);
if (Array.IndexOf(arr, value) > -1)
i--;
else
{
arr[i] = value;
i++;
}
} while (i<arr.Length);
Array.Sort(arr);
var key = r.Next(arr.Length - 1);
foreach (var item in arr)
{
text.Append(item + ",");
}
string qian = text.Remove(text.Length - 1, 1).ToString();
var xzNum = r.Next(20);
//旋转后的数组
var arrLow = new int[20];
Array.ConstrainedCopy(arr, xzNum, arrLow, 0, 20 - xzNum);
Array.ConstrainedCopy(arr, 0, arrLow, 20 - xzNum, xzNum);
text.Clear();
foreach (var item in arrLow)
{
text.Append(item + ",");
}
Console.WriteLine($"旋转前数组:{qian}");
Console.WriteLine($"旋转后数组{text.Remove(text.Length - 1, 1).ToString()}");
Console.WriteLine($"随意旋转后找到最小值所在下标,与值");
var t = info.GetKeyMinIndex(arrLow);
Console.WriteLine($"key:{key},value:{t},index:{Array.IndexOf(arrLow, t)}");
}
}
#endregion
引用类
public class KeyNum
{
public int Start { get; set; }
public int End { get; set; }
}
public class ErFen
{
/// <summary>
/// 获取最大到或等于key的值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public int GetKeyLowMax(int[] arr, int key)
{
return GetMax(arr, 0, arr.Length, key);
}
public KeyNum GetKeyNum(int[] arr, int key)
{
int end = Array.LastIndexOf(arr, key);
int start = Array.IndexOf(arr, key);
return new KeyNum() { End = end, Start = start };
}
/// <summary>
///
/// </summary>
/// <param name="arr"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="key"></param>
/// <returns></returns>
private int GetMax(int[] arr, int start, int end, int key)
{
int index = (start + end) / 2;
if(index==arr.Length-1)
{
if (arr[index] <= key)
return arr[index];
return -1;
}else if (arr[index] <= key && arr[index + 1] > key)
{
return arr[index];
}
else if (arr[index] < key)
{
return GetMax(arr, index + 1, end, key);
}
else
{
return GetMax(arr, start, index - 1, key);
}
}
/// <summary>
///
/// </summary>
/// <param name="arr"></param>
/// <param name="start"></param>
/// <param name="end"></param>
/// <param name="key"></param>
/// <returns></returns>
private int GetMin(int[] arr, int start, int end)
{
int index = (start + end) / 2;
if (index == 0)
{
if (arr[0] > arr[1])
return arr[1];
return arr[0];
} else if (index==arr.Length-2)
{
if (arr[index] > arr[index + 1])
return arr[index + 1];
return arr[index];
}
else if (arr[index - 1] > arr[index + 1])
{
if (arr[index] > arr[index + 1])
{
return arr[index + 1];
}
else
{
return arr[index];
}
}
else if (arr[index] > arr[end])
{
return GetMin(arr, index + 1, end);
}
else
{
return GetMin(arr, start, index - 1);
}
}
public int GetKeyMinIndex(int[] arr)
{
return GetMin(arr, 1, arr.Length - 1);
}
}