一个算法题

题目:

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 2012-04-01 01:32  右耳纹金刀  阅读(508)  评论(0编辑  收藏  举报

导航