一个算法题

题目:

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<intbool> existedNumbers = new Dictionary<intbool>();
            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]);
                    }
                }
            }
        }
复制代码

    } 

 

posted on   右耳纹金刀  阅读(511)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 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——大语言模型本地部署的极速利器

导航

< 2012年4月 >
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5
6 7 8 9 10 11 12

统计

点击右上角即可分享
微信分享提示