1. 程式人生 > >四數問題下邏輯運算子的注意事項

四數問題下邏輯運算子的注意事項

給定一個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。

注意:答案中不可以包含重複的三元組。

例如, 給定陣列 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合為:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
public static List<List<Integer>> fourSum(int[] nums, int target) {
        int firs;
        int seco;
        int thir;
        int four;
        int temp;
        List<List<Integer>> res = new LinkedList<>();
        Arrays.sort(nums);
        for (firs = 0; firs < nums.length; firs++) {
            for (seco = firs + 1; seco < nums.length; seco++) {
                thir = seco + 1;
                four = nums.length - 1;
                while (thir < four) {
                    temp = nums[firs] + nums[seco] + nums[thir] + nums[four];
                    if (temp == target) {
                        res.add(Arrays.asList(nums[firs], nums[seco], nums[thir], nums[four]));
                        while (nums[thir] == nums[thir + 1] && thir < four) thir++;
                        while (nums[four] == nums[four - 1] && thir < four) four--;
                        thir++;
                        four--;
                    } else if (temp > target) {
                        while (nums[four] == nums[four - 1] && four > thir) four--;
                        four--;

                    } else {
                        while (nums[thir] == nums[thir + 1] && thir < four) thir++;
                        thir++;
                    }
                }
            }
        }
        return res;
    }

以上為第一次寫出的解決方法,具體做法是將四數之和轉換為外層迴圈加一個三數之和(而三數之和可以轉換為外層迴圈加雙指標問題)。

但是測試時,輸入陣列{0,0,0,0}與target=0,會在

while (nums[thir] == nums[thir + 1] && thir < four) thir++;

這一語句處報ArrayIndexOutOfBoundsException異常,經過debug後發現,邏輯運算子&&的左右判斷語句的順序影響了程式的正確性。

此時,thir = 3, 先進行判斷nums[thir] == nums[thir + 1],然後判斷thir < four都滿足於是 thir++,此時thir = 4,然後再次進行判斷nums[thir] == nums[thir + 1] ,此時thir + 1 = 4,於是就發生陣列下標越界的異常。

根據邏輯,每次進行比較前應先判斷是否第三個數小於第四個,所以應該將

while (nums[thir] == nums[thir + 1] && thir < four) thir++;
while (nums[four] == nums[four - 1] && thir < four) four--;

中的兩個while迴圈中的邏輯判斷順序調換一下:

while (thir < four && nums[thir] == nums[thir + 1]) thir++;
while (thir < four && nums[four] == nums[four - 1]) four--;

果然調換了一下順序之後就對了,在進行陣列判斷之前,會先判斷thir < four,若thir = 4,則這時已經不滿足了,就不會進行後面的判斷。 

其實程式是次要的,主要是在進行邏輯判斷的時候,一定要注意先後順序(吃了好幾次這樣的虧,特此記錄一下)。