[面试备忘]数组(一维)最大子串总结

求整型数组中最大子串方法总结:

View Code
  1 #include <iostream>
2 #include <cassert>
3
4 #define MAX(a, b) ((a) > (b) ? (a) : (b))
5 //判断两已排序数组是否有相同元素
6 bool sameNumber(const int* preArray, int preSize, const int* postArray, int postSize)
7 {
8 assert( preArray && postArray);
9 int preIndex = 0;
10 int postIndex = 0;
11 while (preIndex != preSize && postIndex != postSize) {
12 if (preArray[preIndex] == postArray[postIndex]) {
13 return true;
14 }
15 if (preArray[preIndex] > postArray[postIndex]) {
16 ++postIndex;
17 } else {
18 ++preIndex;
19 }
20 }
21 return false;
22 }
23
24 //求数组中最大子串 普通方法
25 int getMaxSubArrayNormal(const int* array, int size)
26 {
27 assert(array);
28 int max = array[0];
29 for (int outIndex = 0; outIndex != size; ++outIndex) {
30 int tempValue = 0;
31 for (int inIndex = outIndex; inIndex != size; ++inIndex) {
32 tempValue += array[inIndex];
33 if (tempValue > max) {
34 max = tempValue;
35 }
36 }
37 }
38 return max;
39 }
40
41 //二分方法, 递归实现.
42 int getMaxSubArrayRecursion(const int* array, int size)
43 {
44 if (size == 1) {
45 return array[0];
46 }
47 int tempSum = array[size / 2 - 1];
48 int firstHalfMax = array[size / 2 - 1];
49 for (int index = size / 2 - 2; index >= 0; --index) {
50 tempSum += array[index];
51 if (tempSum > firstHalfMax) {
52 firstHalfMax = tempSum;
53 }
54 }
55 tempSum = array[size / 2];
56 int secondHalfMax = array[size / 2];
57 for (int index = size / 2 + 1; index != size; ++index) {
58 tempSum += array[index];
59 if (tempSum > secondHalfMax) {
60 secondHalfMax = tempSum;
61 }
62 }
63 return MAX(firstHalfMax + secondHalfMax,
64 MAX(getMaxSubArrayRecursion(array, size / 2),
65 getMaxSubArrayRecursion(array + size / 2, size - size / 2)));
66 }
67
68 //动规方法, 元素如果抖为负数返回0
69 int getMaxSubArrayDP(const int* array, int size)
70 {
71 assert(array);
72 int max = 0;
73 int tempSum = 0;
74 for (int index = 0; index != size; ++index) {
75 tempSum += array[index];
76 if (tempSum > max) {
77 max = tempSum;
78 } else if (tempSum < 0) {
79 tempSum = 0;
80 }
81 }
82 return max;
83 }
84
85 //动规, 对元素组合没有要求, 返回实际最大子串
86 int getMaxSubArrayDPGeneral(const int* array, int size)
87 {
88 assert(array);
89 int max = array[0];
90 int tempSum = array[0];
91 for (int index = 1; index != size; ++index) {
92 if (tempSum < 0) {
93 tempSum = array[index];
94 } else {
95 tempSum += array[index];
96 }
97 if (tempSum > max) {
98 max = tempSum;
99 }
100 }
101 return max;
102 }
103
104 //同上, 不过额外返回最大子串起止下标
105 int getMaxSubArrayDPGeneralWithRange(const int* array, int size, int& startIndex, int& endIndex)
106 {
107 assert(array);
108 int max = array[0];
109 int tempSum = array[0];
110 startIndex = endIndex = 0;
111 for (int index = 1; index != size; ++index) {
112 bool updateStartIndex = false;
113 if (tempSum < 0) {
114 updateStartIndex = true;
115 tempSum = array[index];
116 } else {
117 tempSum += array[index];
118 }
119 if (tempSum > max) {
120 if (updateStartIndex) {
121 startIndex = index;
122 }
123 endIndex = index;
124 max = tempSum;
125 }
126 }
127 return max;
128 }
129
130 int main()
131 {
132 int preArray[] = { 1, 3, 4, 6, 8, 9 };
133 int postArray[] = { 5, 8, 10 };
134 std::cout << std::boolalpha << sameNumber(preArray,
135 sizeof(preArray) / sizeof(*preArray), postArray,
136 sizeof(postArray) / sizeof(*postArray)) << std::endl;
137 int maxSubArray[] = { -14, 3, 5, -6, 5, -3, -2, -1, 16, -10, -2 };
138 int startIndex = 0;
139 int endIndex = 0;
140 std::cout << getMaxSubArrayNormal(maxSubArray, sizeof(maxSubArray) / sizeof(*maxSubArray)) << ' '
141 << getMaxSubArrayDP(maxSubArray, sizeof(maxSubArray) / sizeof(*maxSubArray)) << ' '
142 << getMaxSubArrayDPGeneral(maxSubArray, sizeof(maxSubArray) / sizeof(*maxSubArray)) << ' '
143 << getMaxSubArrayDPGeneralWithRange(maxSubArray, sizeof(maxSubArray) / sizeof(*maxSubArray), startIndex, endIndex) << ' '
144 << getMaxSubArrayRecursion(maxSubArray, sizeof(maxSubArray) / sizeof(*maxSubArray)) << std::endl;
145 for (int index = startIndex; index <= endIndex; ++index) {
146 std::cout << maxSubArray[index] << ' ' << std::flush;
147 }
148 std::cout << std::endl;
149 return 0;
150 }

首尾"相连"数组求解于上面递归求解方法类似,将问题分解为正常解于跨界最大子串比较问题.

posted @ 2011-08-30 16:12  lifengzhong  阅读(229)  评论(0编辑  收藏  举报