我們知道:
1+2 = 3;
4+5 = 9;
2+3+4 = 9。
等式的左邊都是兩個或兩個以上連續(xù)的自然數(shù)相加,是不是所有的整數(shù)都可以寫成這樣的形式呢?
問題1: 對于一個64位正整數(shù),輸出它所有可能的連續(xù)自然數(shù)(兩個以上)之和的算式。
問題2: 大家在測試上面程序的過程中,肯定會注意到有一些數(shù)字不能表達(dá)為一系列連續(xù)的自然數(shù)
之和,例如32好像就找不到。那么,這樣的數(shù)字有什么規(guī)律呢?能否證明你的結(jié)論?
問題3: 在64位正整數(shù)范圍內(nèi),子序列數(shù)目最多的數(shù)是哪一個?
問題一解法:雙指針遍歷
這題有兩種解法, 其中一種便是雙指針法,還有一種比較巧妙,利用了數(shù)學(xué)方法,簡單來說是求出一個公式來。這里只說雙指針的解法。
這里需要一個轉(zhuǎn)化,把求n中所有可能的連續(xù)自然數(shù)之和歸約為在數(shù)組{1,2,3,...,n}中找所有連續(xù)子序列和等于n的問題。這里同樣也是這樣一個場景:對有序數(shù)組如何遍歷來求得符合要求的數(shù)據(jù)集合?這時的雙指針可以不是一頭一尾了,而是兩個都指向頭部,這樣可以以高效的順序遍歷我們要找的所有集合。初始設(shè)i=j=1,這里同樣會出現(xiàn)三種情況:
sum[i,j] == sum, 直接輸出i到j(luò)的值,并把i+1,j+1,因?yàn)橹皇莍+1肯定是不等的,因?yàn)楹托×耍瑯觠+1只會使和變大,所以兩個都要往前加(注意這里指針不用考慮減小,因?yàn)檫@在以前就考慮過了)sum[i,j] < sum,說明偏小,那么提高j來使得和變大才有可能相等sum[i,j] > sum,說明偏大,那么提高i來使得和變小才有可能相等這樣,代碼就出來了:
public static void GetAnswer(int n) { int i =0, j = 0; while (i <= (n / 2) && j <= n) { int sum = (j + i)*(j - i + 1) / 2; if (sum == n) { for (int k = i; k <= j; k++) Console.WriteLine(k); i++; j++; } else if (sum < n) //sum[i..j]<n,只能提高j以增大sum { j++; } else //sum[i..j]>n,只能提高i以減小sum { i ++; } } }所謂雙指針,是利用兩個指針對一個有序數(shù)組進(jìn)行遍歷,查找出符合要求的數(shù)據(jù)集合。相信大家都接觸到了這種思維模式的解題方法,只是沒有注意到罷了。
新聞熱點(diǎn)
疑難解答