国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

LintCode547/548_求數組交集不同解法小結

gxyz / 657人閱讀

摘要:求數組交集不同解法小結聲明文章均為本人技術筆記,轉載請注明出處求數組交集要求元素不重復,給出兩個數組,求二者交集且元素不重復,查找會超時解法一排序二分查找算法超時主要發生在大數組查找過程,因此采用二分查找提升查找效率,交集用保存實現去重解法

LintCode547/548_求數組交集不同解法小結

[TOC]

聲明

文章均為本人技術筆記,轉載請注明出處:
[1] https://segmentfault.com/u/yzwall
[2] blog.csdn.net/j_dark/

LintCode547:求數組交集_要求元素不重復

LintCode547,給出兩個數組,求二者交集且元素不重復,$O(N^{2})$查找會超時;

解法一:排序+二分查找

$O(N ^{2})$算法超時主要發生在大數組查找過程,因此采用二分查找提升查找效率,交集用HashSet保存實現去重;

/**
 * 解法1:排序+二分+HashSet去重
 * http://www.lintcode.com/zh-cn/problem/intersection-of-two-arrays/
 * 求數組交集,要求元素不重復出現
 * @author yzwall
 */
class Solution {
    public int[] intersection(int[] num1, int[] num2) {
        int[] results;
        if (num1 == null || num1.length == 0 || num2 == null || num2.length == 0) {
            results = new int[0];
            return results;
        }
        
        HashSet set = new HashSet<>();
        Arrays.sort(num1);
        Arrays.sort(num2);
        int index2 = 0;
        for (int i = 0; i < num1.length; i++) {
            // num2是子集
            if (index2 > num2.length - 1) {
                break;
            }
            int index = binarySearch(num2, index2, num1[i]);
            if (index != -1) {
                // set去重
                set.add(num1[i]);
                // num2指針移動
                index2 = index;
            }
        }
        
        results = new int[set.size()];
        int i = 0;
        for (Integer cur : set) {
            results[i++] = cur.intValue();
        }
        return results;
    }
    
    // Index2~num.length - 1,經典二分查找
    private int binarySearch(int[] num, int index2, int target) {
        int start = index2;
        int end = num.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (num[mid] == target) {
                return mid;
            } else if (num[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (num[start] == target) {
            return start;
        }
        if (num[end] == target) {
            return end;
        }
        return -1;
    }
}
解法二:HasSet暴力去重

直接運用兩個HashSet實現去重求交集,與解法一相比實現簡單;

/**
 * 解法2:HashSet暴力去重
 * http://www.lintcode.com/zh-cn/problem/intersection-of-two-arrays/
 * 求數組交集,要求元素不重復出現
 * @author yzwall
 */
class Solution {
    public int[] intersection(int[] num1, int[] num2) {
        int[] results;
        if (num1 == null || num1.length == 0 || num2 == null || num2.length == 0) {
            results = new int[0];
            return results;
        }
        HashSet hash1 = new HashSet<>();
        for (int i = 0; i < num1.length; i++) {
            hash1.add(num1[i]);
        }
        HashSet hash2 = new HashSet<>();
        for (int i = 0; i < num2.length; i++) {
            if (hash1.contains(num2[i])) {
                hash2.add(num2[i]);
            }
        }
        
        results = new int[hash2.size()];
        int i = 0;
        for (Integer num : hash2) {
            results[i++] = num;
        }
        
        return results;
    }
}
解法三:雙指針法(重視)

通過雙指針求交集,必須首先將求交集的兩數組排序

/**
 * 解法3:雙指針法
 * http://www.lintcode.com/zh-cn/problem/intersection-of-two-arrays/
 * 求數組交集,要求元素不重復出現
 * @author yzwall
 */
class Solution {
    public int[] intersection(int[] num1, int[] num2) {
        int[] results;
        if (num1 == null || num1.length == 0 || num2 == null || num2.length == 0) {
            results = new int[0];
            return results;
        }
        Arrays.sort(num1);
        Arrays.sort(num2);
        int i = 0, j = 0;
        int index = 0;
        int[] temp = new int[num1.length];
        while (i < num1.length && j < num2.length) {
            if (num1[i] == num2[j]) {
                // temp[index - 1] != num1[i]去重
                if (index == 0 || temp[index - 1] != num1[i]) {
                    temp[index++] = num1[i];
                }
                i++;
                j++;
            } else if (num1[i] < num2[j]) {
                i++;
            } else {
                j++;
            }
        }
        
        i = 0;
        results = new int[index];
        for (i = 0; i < index; i++) {
            results[i] = temp[i];
        }
        return results;
    }
}
LintCode548:求數組交集變種

在求數組交集的基礎上,要求交集元素出現次數與在數組中出現次數相同;

解法一:HashMap統計次數實現

通過HashMap記錄數組中每個元素與對應的出現次數;

/**
 * 解法2:HashMap統計重復出現次數
 * http://www.lintcode.com/zh-cn/problem/intersection-of-two-arrays-ii/
 * 求兩數組交集,要求交集元素按照最小出現次數出現
 * @author yzwall
 */
class Solution {
    public int[] intersection(int[] num1, int[] num2) {
        int[] results;
        if (num1 == null || num1.length == 0 || num2 == null || num2.length == 0) {
            results = new int[0];
            return results;
        }
        
        HashMap hash = new HashMap<>();
        for (int i = 0; i < num1.length; i++) {
            if (hash.containsKey(num1[i])) {
                hash.put(num1[i], hash.get(num1[i]) + 1);
            } else {
                hash.put(num1[i], 1);
            }
        }
        
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < num2.length; i++) {
            if (hash.containsKey(num2[i]) && hash.get(num2[i]) > 0) {
                list.add(num2[i]);
                hash.put(num2[i], hash.get(num2[i]) - 1);
            }
        }
        
        results = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            results[i] = list.get(i);
        }
        return results;
    }
}
解法二:排序+二分查找變種+雙指針

變種二分查找:與經典二分不同,解法二中二分查找用于找到查找目標第一次出現位置;
雙指針解法:經過排序后,假設兩數組中擁有某個交集元素cur, 通過二分查找到cur在第二個數組中的位置index,通過雙指針cnt1cnt2統計交集元素cur在兩個數組中各自出現的總次數,較小者表示該交集元素在交集中出現的次數

/**
 * 解法1:排序+二分查找+雙指針
 * http://www.lintcode.com/zh-cn/problem/intersection-of-two-arrays-ii/
 * 求兩數組交集,要求交集元素按照最小出現次數出現
 * @author yzwall
 */
class Solution3 {
    public int[] intersection(int[] num1, int[] num2) {
        int[] results;
        if (num1 == null || num1.length == 0 || num2 == null || num2.length == 0) {
            results = new int[0];
            return results;
        }
        
        ArrayList list = new ArrayList<>();
        Arrays.sort(num1);
        Arrays.sort(num2);
        int index2 = 0;
        int i = 0;
        while(i < num1.length) {
            // num2是子集
            if (index2 > num2.length - 1) {
                break;
            }
            int cnt1 = 1, cnt2 = 1;
            int cur = num1[i];
            int index = binarySearch(num2, index2, cur);
            if (index != -1) {
                // 查找交集元素cur在數組num1中出現總次數
                for (int k = 1; k < num1.length && i + k < num1.length; k++) {
                    if (num1[i + k] != cur) {
                        break;
                    }
                    cnt1++;
                }
                // 查找交集元素cur在數組num2中出現總次數
                for (int k = 1; k < num2.length && index + k < num2.length; k++) {
                    if (num2[index + k] != cur) {
                        break;
                    }
                    cnt2++;
                }
                int min = Math.min(cnt1, cnt2);
                for (int k = 0; k < min; k++) {
                    list.add(cur);
                }
                // num2指針移動
                index2 += cnt2;
            }
            // num1指針移動
            i += cnt1;
        }
        
        results = new int[list.size()];
        i = 0;
        for (Integer cur : list) {
            results[i++] = cur.intValue();
        }
        return results;
    }
    
    // 返回target第一次出現位置,target不存在返回-1
    private int binarySearch(int[] num, int index2, int target) {
        int start = index2;
        int end = num.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (num[mid] == target) {
                end = mid;
            } else if (num[mid] < target) {
                start = mid;
            } else {
                end = mid;
            }
        }
        if (num[start] == target) {
            return start;
        }
        if (num[end] == target) {
            return end;
        }
        return -1;
    }
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70036.html

相關文章

  • 兩數之和問題各變種多解法小結

    摘要:兩數之和問題各變種多解法小結聲明文章均為本人技術筆記,轉載請注明出處兩數之和等于題目大意給出未排序數組和指定目標,返回數組中兩數之和的組合元素下標要求下標從開始,而且,保證題目中有且只有個可行解解法暴力時間復雜度求解解題思路暴力二重循環求解 兩數之和問題各變種多解法小結 聲明 文章均為本人技術筆記,轉載請注明出處:[1] https://segmentfault.com/u/yzwal...

    lentoo 評論0 收藏0
  • 表達式類算法題小結

    摘要:將表達式轉換為逆波蘭式,然后求值轉換中綴表達式為逆波蘭式魯棒性檢測,表達式中沒有操作數計算逆波蘭式值參考 表達式類算法題小結 [TOC] 聲明 文章均為本人技術筆記,轉載請注明出處:[1] https://segmentfault.com/u/yzwall[2] blog.csdn.net/j_dark/ 表達式分類 根據運算符與相關操作操作數的位置不同,將表達式分為前綴,中綴和后綴表...

    Heier 評論0 收藏0
  • TypeScript實現數組相關簡單算法

    摘要:本文只是簡單理解算法,并不會深入的討論。大部分來自數組部分。如果數組中每個元素都不相同,則返回。示例輸入輸出加給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。盡量減少操作次數。 算法(algorithm),在數學(算學)和計算機科學之中,為任何良定義的具體計算步驟的一個序列,常用于計算、數據處理和自動推理。精確而言,算法是一個表示為有限長列表的有效方法。算法應包含清晰...

    cloud 評論0 收藏0
  • 數組差/交集函數-php數組函數(二)

    摘要:求數組差集函數函數只檢查了多維數組中的一維。自定義函數必須返回一個小于零,等于零,或大于零的整數。用自定義函數比較的值,函數參數為數組的值。 求數組差集函數 函數只檢查了多維數組中的一維。可以用 array_diff($array1[0], $array2[0]) 檢查更深的維度。 u:自定義函數比較,a(association):同時比較鍵和值。 自定義函數callable $v...

    ChristmasBoy 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<