一个算法题
题目:
http://weibo.com/1435323715/ycrmi0mpI
@belleveinvis : 刚才群里看到的一个编程题送各位:给定一个 array,求出里面最长的连续的一段,它由连续的数组成,顺序任意。例如 (5 1 3 2) 就返回 (1 3 2),(5 3 1 4 2) 就返回 (5 3 1 4 2)。@老赵 @装配脑袋 @朴灵
思路:
其实就两关键问题:
1.如何判断几个数字是由“连续的数字组成”
一堆数里如果没有相同的数字,而且这些数里最大数减最小数正好等于这堆数的数量(严格的说再减一),那他们就是由连续的数组成的。不信可以随便找几个数来验证这个逻辑。
2.解决了1之后,如何在整个数组中去用1的办法寻找所有满足条件的子数组。
穷举不可避免,只是尽量有点效率。我的做法是从左到右遍历数组。把遍历的那个数作为起点,往右按照上面的办法寻找满足条件的子数组,找到就缓存下来,下次找比它大的,从而得到满足条件的最长的一段。
解答(未做太多优化):
/// <summary>
/// new GetMaxChildArray(new int[] { 5, 6, 3, 1, 4, 2 }).Go()
/// </summary>
class GetMaxChildArray
{
int[] array;
List<int> maxChild = new List<int>();
/// <summary>
/// 初始化,传进来一个array
/// </summary>
/// <param name="_array"></param>
public GetMaxChildArray(int[] _array)
{
if (_array == null || _array.Length == 0)
throw new ArgumentException();
this.array = _array;
}
/// <summary>
/// GO!
/// </summary>
/// <returns></returns>
public int[] Go()
{
//关键:从首位遍历数组
for (int i = 0, length = this.array.Length; i < length - maxChild.Count; i++)
{
//然后从当前位(i)作为子数组起点,寻找满足要求的子数组
FindChindArrayFromIndex(i);
}
return maxChild.ToArray();
}
private void FindChindArrayFromIndex(int index)
{
int max = int.MinValue,
min = int.MaxValue,
reginSize = 0,
leftCount = this.array.Length - index,
current = 0;
Dictionary<int, bool> existedNumbers = new Dictionary<int, bool>();
for (int i = index, length = this.array.Length; i < length; i++)
{
current = this.array[i];
//退出条件1:碰上相同的数
if (existedNumbers.ContainsKey(current))
return;
existedNumbers.Add(current, true);
max = Math.Max(max, current);
min = Math.Min(min, current);
reginSize = max - min;
//退出条件2:此次碰上了不能搭配的最大最小数
if (reginSize > leftCount)
return;
//命中
if (reginSize == i - index && reginSize >= this.maxChild.Count)
{
this.maxChild = new List<int>();
for (int ii = index; ii <= i; ii++)
{
this.maxChild.Add(this.array[ii]);
}
}
}
}
/// new GetMaxChildArray(new int[] { 5, 6, 3, 1, 4, 2 }).Go()
/// </summary>
class GetMaxChildArray
{
int[] array;
List<int> maxChild = new List<int>();
/// <summary>
/// 初始化,传进来一个array
/// </summary>
/// <param name="_array"></param>
public GetMaxChildArray(int[] _array)
{
if (_array == null || _array.Length == 0)
throw new ArgumentException();
this.array = _array;
}
/// <summary>
/// GO!
/// </summary>
/// <returns></returns>
public int[] Go()
{
//关键:从首位遍历数组
for (int i = 0, length = this.array.Length; i < length - maxChild.Count; i++)
{
//然后从当前位(i)作为子数组起点,寻找满足要求的子数组
FindChindArrayFromIndex(i);
}
return maxChild.ToArray();
}
private void FindChindArrayFromIndex(int index)
{
int max = int.MinValue,
min = int.MaxValue,
reginSize = 0,
leftCount = this.array.Length - index,
current = 0;
Dictionary<int, bool> existedNumbers = new Dictionary<int, bool>();
for (int i = index, length = this.array.Length; i < length; i++)
{
current = this.array[i];
//退出条件1:碰上相同的数
if (existedNumbers.ContainsKey(current))
return;
existedNumbers.Add(current, true);
max = Math.Max(max, current);
min = Math.Min(min, current);
reginSize = max - min;
//退出条件2:此次碰上了不能搭配的最大最小数
if (reginSize > leftCount)
return;
//命中
if (reginSize == i - index && reginSize >= this.maxChild.Count)
{
this.maxChild = new List<int>();
for (int ii = index; ii <= i; ii++)
{
this.maxChild.Add(this.array[ii]);
}
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器