在一個數組中查詢任意個數和為m的的組合
阿新 • • 發佈:2018-12-14
最近比較鬱悶,遇到幾次類似的題目了,現在打算總結一下,防止以後又忘了
1、輸入一個遞增排序的陣列和一個數字S,在陣列中查詢兩個數,使得他們的和正好是S,如果有多對數字的和等於S,輸出兩個數的乘積最小的。
import java.util.ArrayList; public class Solution { public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) { ArrayList<Integer> list = new ArrayList<>(); if (array.length == 0) { return list; } int left = 0; int right = array.length-1; while (left < right) { if (array[left]+array[right]==sum){ list.add(array[left]); list.add(array[right]); return list; } if (array[left]+array[right]>sum){ right--; } if (array[right]+array[left]<sum){ left++; } } return list; } }
直接計算即可,比較簡單
2、劍指offer上一題目 小明很喜歡數學,有一天他在做數學作業時,要求計算出9~16的和,他馬上就寫出了正確答案是100。但是他並不滿足於此,他在想究竟有多少種連續的正數序列的和為100(至少包括兩個數)。沒多久,他就得到另一組連續正數和為100的序列:18,19,20,21,22。現在把問題交給你,你能不能也很快的找出所有和為S的連續正數序列? Good Luck!
import java.util.ArrayList; public class Solution { public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) { ArrayList<ArrayList<Integer>> listAll = new ArrayList<>(); for (int i = (int) Math.sqrt(sum * 2); i >= 2; i--) { if (((i & 1) == 1 && sum % i == 0) || (sum % i) * 2 == i) { ArrayList<Integer> list = new ArrayList<>(); for (int j = 0, k = (sum / i) - (i-1)/ 2; j< i; j++, k++) { list.add(k); } listAll.add(list); } } return listAll; } }
3、最近遇到比較多的,輸入兩個數n,m,要求輸出1-n中所有和為m的組合
思路比較簡單1-n個每個元素無非就是兩種情況,加入或者不加入 因此我直接採用遞迴獲取所有的組合,1表示加入這個元素,0 表示不加入這個元素,最終求出所有的情況
package com.sharetime.test; import java.util.*; /** * @Author: yd * @Date: 2018/10/9 20:02 * @Version 1.0 */ public class Main { public static void main(String[] args) { new Main().getInfo(); } public void getInfo() { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); getlist(m); for (List<Integer> sh : listAll) { int add = 0; List<Integer> lk = new ArrayList<>(); for (int i = 0; i < sh.size(); i++) { if (sh.get(i) == 1) { add += i + 1; lk.add(i + 1); } } if (add == m) res.add(new ArrayList<>(lk)); } System.out.println(res); } List<Integer> list = new ArrayList<>(); List<List<Integer>> listAll = new ArrayList<>(); List<List<Integer>> res = new ArrayList<>(); /** * 獲取所有組合情況 * * @param target */ void getlist(int target) { if (target == 0) { listAll.add(new ArrayList<>(list)); return; } list.add(0); getlist(target - 1); list.remove(list.size() - 1); list.add(1); getlist(target - 1); list.remove(list.size() - 1); } }
這樣做時間複雜度確實有點大,可以進行一定優化,比如講遞迴改成迴圈 還有 100110001如果這個組合和為m了那麼就沒必要再判斷 100111111了,因為肯定大於m,(當然這是在數都為正數的情況下)