質問とテスト
package sword041;
/*
题目一:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。假设有多个数字的和等于s,输出随意一对就可以。
比如输入数组{1,2,4,7,11,15}和数字15.因为4+11=15。因此输出4和11.
题目二:输入一个正数s,打印出全部的和为s的连续正数序列(至少含有两个数字)。
比如输入15。因为1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续的序列1——5,4——6。7——8.
*/
import java.util.List;
public class main {
public static void main(String[] args) {
int[][] testTable = {
{1,2,4,7,11,15},{-1,-100,3,99}};
int[] testTable2={15,1};
for (int i=0;i<testTable.length;i++) {
test(testTable[i],testTable2[i]);
}
int[] testTable3 = {15,10,6};
for (int ito : testTable3) {
test2(ito);
}
}
private static void test(int[] ito,int ito2) {
Solution solution=new Solution();
long begin = System.currentTimeMillis();
for (int i = 0; i < ito.length; i++) {
System.out.print(ito[i]+" ");
}
System.out.println();
//开始时打印数组
System.out.println(ito2);
System.out.println( "rtn=" );
solution.findNumbersWithSum(ito,ito2);//执行程序
long end = System.currentTimeMillis();
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
private static void test2(int ito) {
Solution solution = new Solution();
long begin = System.currentTimeMillis();
System.out.print(ito);
System.out.println();
//开始时打印数组
System.out.println( "rtn=" );
solution.findContinuousSequence(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
トピック1(成功)
配列と数値sを昇順で入力し、それらの合計が正確にsになるように配列内の2つの数値を見つけます。複数の数値の合計がsに等しい場合は、任意のペアを出力するだけです。
たとえば、入力配列{1、2、4、7、11、15}と数値15。4+11 = 15なので、4と11が出力されます。
多くの人はすぐにO(n2)メソッドを考えます。つまり、最初に配列内の数値を修正してから、配列内の残りのn-1個の数値の合計とその合計がsに等しいかどうかを判断します。
次に、より良いアルゴリズムを探します。最初に配列内の2つの数値を選択し、それらの合計が入力sに等しい場合、探している2つの数値を見つけました。s未満の場合はどうなりますか?2つの数値の合計が大きくなることを願っています。配列はすでにソートされているので、小さい方の番号の後に番号を選択することを検討できます。後ろの数が大きいので、これら2つの数の合計も大きくなるはずです。これは、入力数sと等しくなる可能性があります。同様に、2つの数値の合計が入力された数値よりも大きい場合、前の数値が小さいため、大きい数値の前の数値を選択できます。
トピック2(成功)
正の数sを入力し、合計がsになるすべての連続する正の数シーケンス(少なくとも2つの数を含む)を出力します。たとえば、1 + 2 + 3 + 4 + 5 = 4 + 5 + 6 = 7 + 8 = 15であるため、15を入力すると、結果は3つの連続したシーケンス1——5,4——6,7——を出力します。 8。
以前の経験では、シーケンスの最小値と最大値をそれぞれ表すために、小さいツリーと大きいツリーの2つを使用することも検討しています。まず、smallを1に、bigを2に初期化します。smallからbigへのシーケンスの合計がsより大きい場合、シーケンスから小さい値を削除できます。つまり、smallの値を増やします。小さいものから大きいものへのシーケンスの合計がs未満の場合、大きい値を増やして、このシーケンスにさらに多くの数値を含めることができます。このシーケンスには少なくとも2つの数値が必要であるため、(1 + s)/ 2まで小さく増加し続けます。
package sword041;
class Solution {
public void findNumbersWithSum(int[] nums, int k) {
int length=nums.length;
if(length==0 || length == 1){
return;
}
int begin = 0;
int end = length -1;
while(begin <= end) {
int sum = nums[begin] + nums[end];
if(sum == k) {
System.out.println(nums[begin] + " "+ nums[end]);
return;
}
if(sum > k) {
end--;
}else {
begin++;
}
}
}
public void findContinuousSequence(int k) {
if(k <= 2) {
return;
}
int begin = 1;
int end = 2;
int sum = 3;
while(begin <= end && end <= k) {
if(sum == k) {
if(begin != end) {
System.out.println(begin + " "+ end);
}
end++;
sum+=end;
continue;
}
if(sum > k && begin != end) {
sum-=begin;
begin++;
}else {
end++;
sum+=end;
}
}
}
}