a few solutions
Synopsis:\n\nIt is more simple to include values than exclude values!\n\nGame Plan: \n1. Let N be the cardinality of the input array A and let threshold T be N 
**Synopsis:**\n\nIt is more simple to *include* values than *exclude* values!\n\n**Game Plan:** \n1. Let `N` be the cardinality of the input array `A` and let threshold `T` be `N / 2`\n2. Let `A` and `B` be sets from input arrays `A` and `B` correspondingly\n3. Further reduce `A` and `B` as **mutually exclusive** sets, ie. all values in `A` *not* in `B` and vice versa all values in `B` *not* in `A`, and let `C` be the **mutually exclusive** set of common values within the set intersection of `A` and `B`\n4. We can take up to threshold `T` of each mutually exclusive set `A` and `B` separately and distinctly; and we can also "fill in the potential leftover space available" in `A` inclusive-or `B` with common values `C` (\u2B50\uFE0F Note: \uD83D\uDC40 see **Supplemental** \uD83C\uDF5E "breadcrumbs" below for iterative details for how we arrived "here" \uD83C\uDFAF)\n\n![image](https://assets.leetcode.com/users/images/01f31034-6bce-4977-a53c-40669fe7f16c_1705422440.3127573.jpeg)\n\n*Kotlin*\n```\ntypealias VI = IntArray\nclass Solution {\n    fun maximumSetSize(A_: VI, B_: VI): Int {\n        var N = A_.size\n        var T = N / 2\n        var A = A_.toSet()\n        var B = B_.toSet()\n        var C = A.intersect(B)\n        var a = Math.min(A.filter{ !C.contains(it) }.size, T)\n        var b = Math.min(B.filter{ !C.contains(it) }.size, T)\n        var c = C.size\n        return Math.min(a + b + c, N)\n    }\n}\n```\n\n*Javascript*\n```\nlet maximumSetSize = (A, B, C = null) => {\n    let N = A.length,\n        T = Math.floor(N / 2);\n    A = new Set(A);\n    B = new Set(B);\n    C = new Set([...A].filter(x => B.has(x)));\n    [A, B] = [new Set([...A].filter(x => !B.has(x))), new Set([...B].filter(x => !A.has(x)))];\n    let a = Math.min(A.size, T),\n        b = Math.min(B.size, T),\n        c = C.size;\n    return Math.min(a + b + c, N);\n};\n```\n\n*Python3*\n```\nclass Solution:\n    def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n        N = len(A)\n        T = N // 2\n        A = set(A)\n        B = set(B)\n        A, B, C = A - B, B - A, A & B\n        a, b, c = min(len(A), T), min(len(B), T), len(C)\n        return min(a + b + c, N)\n```\n\n*Rust*\n```\nuse std::cmp::min;\nuse std::collections::HashSet;\ntype VI = Vec<i32>;\ntype Set = HashSet<i32>;\nimpl Solution {\n    pub fn maximum_set_size(mut A: VI, mut B: VI) -> i32 {\n        let N = A.len();\n        let T = N / 2;\n        let mut A = A.drain(..).collect::<Set>();\n        let mut B = B.drain(..).collect::<Set>();\n        let mut C = Set::new();\n        for x in A.clone() {\n            if B.contains(&x) {\n                C.insert(x);\n            }\n        }\n        for same in &C {\n            A.remove(same);\n            B.remove(same);\n        }\n        let a = min(A.len(), T);\n        let b = min(B.len(), T);\n        let c = C.len();\n        min(a + b + c, N) as i32\n    }\n}\n```\n\n*C++*\n```\nclass Solution {\npublic:\n    using VI = vector<int>;\n    using Set = set<int>;\n    int maximumSetSize(VI& A_, VI& B_, Set C = {}) {\n        auto N = A_.size(),\n             T = N / 2;\n        Set A{ A_.begin(), A_.end() },\n            B{ B_.begin(), B_.end() };\n        set_intersection(A.begin(), A.end(), B.begin(), B.end(), inserter(C, C.end()));\n        erase_if(A, [&](auto x) { return C.find(x) != C.end(); });\n        erase_if(B, [&](auto x) { return C.find(x) != C.end(); });\n        auto a = min(A.size(), T),\n             b = min(B.size(), T),\n             c = C.size();\n        return min(a + b + c, N);\n    }\n};\n```\n\n---\n\n**Supplemental:** \uD83C\uDF5E Breadcrumbs for how we arrived "here."  -- I had a hard time on this question until I looked at hint #1, ie. it is more simple to create a set by adding half rather than removing half.\n\n```\n# 9:03am -\n\n# we must remove half of A\n#  "   "    "   "   " "  B\n\n# return A + B\n\n# goal is to maximumize the cardinal of the set A + B\n\n# question: how to maximumize the set A + B\n\n# different values in A and B increases the size of the set\n#   same values    "    "   "decreases" <-- stays same, not really decreaseing, but certainly not increasing!\n\n# continuously remove the same value between A and B such that one of those same values will remain\n# ie. use a heap to track maximum counts of values between A and B\n\n# ok that sounds good, let\'s see what happens\n\n# 9:07am - implementation begins\n\n\n# 9:10am - hold up, actually I\'m not exactly certain how to choose here, I kinda understand high-level strategy\n#          but need to come up with some pseduocode to iron out the details...\n\n# lets look at a concrete example:\n\n# ex1:\n\n# A = [1,1,2,2]\n# B = [1,1,1,1]\n#      X X\n\n# ex2:\n\n# [1,2,3,4,5,6]\n# [2,2,2,3,3,3]\n#    X X     X\n\n# ex3:\n\n# [1,1,2,2,3,3]\n# [4,4,5,5,6,6]\n#  X   X   X\n\n# question: can we perform validation of a guess in linear time? I dunno\n\n# here\'s the deal:\n\n# from A\'s perspective, it is optimal to remove everything that exists in B (ie. the overlapping intersection between A and B)\n# otherwise if nothing overlaps, then remove most frequent value?\n\n# actually maybe I\'m overthinking this?\n\n# almost always when I miss problems it is because I make things too complicated\n\n# so KISS == keep it super simple\n\n# what if we just greedily remove most frequent values from A and B, then take the union of that as the best answer?]\\\n# ya that seems more simple, right?\n\n# 9:18am - implementation begins\n# 9:21am - implementation ends\n\n# class Solution:\n#     def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n#         def f(A):\n#             N = len(A)\n#             q = [(-cnt, x) for x, cnt in Counter(A).items()]; heapify(q)\n#             while N // 2 < len(q):\n#                 heappop(q)\n#             return set(x for _, x in q)\n#         return len(f(A) | f(B))\n        \n# 9:22am - wrong answer\n\n# Submission Detail\n# 316 / 969 test cases passed.\n# Status: Wrong Answer\n# Submitted: 0 minutes ago\n# Input:\n# [9,8,4,7]\n# [5,5,9,5]\n# Output:\n# 3\n# Expected:\n# 4\n\n# ok ya, so we\'re not taking into account the hollistic set union between A+B, good try though, it is super simple!\n\n# I suppose we would always want to greedily consume all values in common amoungst each array A, B *separately*\n# then greedily consume all values in common amoungst each array A, B *together*\n# finally we must remove values that would have been helpful to include in the answer, but we cannot afford to do so, since\n# we must remove half of the values\n# ok so that\'s where the inversion comes from, right?\n\n\n# 9:34am - ok let\'s take a break, I think I\'m on the right track:\n\n# from A\'s perspective:\n# * remove cnt-1 values for each x in common with itself (leaving just 1 of each x)\n# * completely remove all instances of the value x which exist in B\n# * aribtrarily remove remaining values x,y,z which do not exist in B\n\n# from B\'s perspective: same deal\n# * remove cnt-1 values for each x in common with itself (leaving just 1 of each x)\n# * completely remove all instances of the value x which exist in A\n# * aribtrarily remove remaining values x,y,z which do not exist in A\n\n# 9:38am - alright whatever, now that it is written out verbosely might as well implement it...\n# 9:46am - well that\'s correct for example 1 and example 3, but fails for example 2\n\n# class Solution:\n#     def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n#         N = len(A)\n#         T = N // 2\n#         same = lambda A: sum(cnt - 1 for cnt in Counter(A).values())\n#         def f(A, B):\n#             take = same(A)\n#             if T <= take:\n#                 return set(A)\n#             take += len(set(A) & set(B))\n#             if T <= take:\n#                 return set(A) - set(B)\n#             need = T - take\n#             return set(list(A)[:need])\n#         return len(f(A, B) | f(B, A))\n\n# Wrong Answer\n# Runtime: 75 ms\n# Your input\n# [1,2,1,2]\n# [1,1,1,1]\n# [1,2,3,4,5,6]\n# [2,3,2,3,2,3]\n# [1,1,2,2,3,3]\n# [4,4,5,5,6,6]\n# Output\n# 2\n# 3\n# 6\n# Expected\n# 2\n# 5\n# 6\n\n# 9:47am - let\'s take a break for real\'s...\n\n# question: how to remove same values optimally?  right?  keeping the different values if we can, since that makes the set bigger\n\n# key hint 1: that I missed, but almost got... LOL\n\n# Removing n / 2 elements from each array is the same as keeping n / 2 elements in each array.\n\n# game plan: sort A and B, then use i and j to cherry pick unseen values?\n# hold up, how to only take N/2 each?  let\'s come back tomorrow fresh...\n\n# class Solution:\n#     def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n#         N = len(A)\n#         A.sort()\n#         B.sort()\n#         seen = set()\n#         i, j = 0, 0\n#         while i < N or j < N:\n#             while i < N and A[i] in seen:\n#                 i += 1\n#             if i < N:\n#                 seen.add(A[i])\n#         return len(seen)\n\n# 8:33am - \n# 8:52am - AC in ~19 minutes\n\n# greedily take values in A that are not in B\n# "    "     "     "   in B that are not in A\n\n# take up to threshold T=N/2 of all values in A that are not in B\n#  "     "        "         "       "     "   B                 A\n\n# if they exist, then the leftovers are each array\'s unused values in A and/or B\n\n# leftovers = min(T - min(T, len(A)), T - min(T, len(B)))\n\n# class Solution:\n#     def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n#         N = len(A)\n#         T = N // 2\n#         A = set(A)\n#         B = set(B)\n#         C = A & B\n#         f = lambda A, B: set(x for x in A if x not in B)\n#         A, B = f(A, B), f(B, A)\n#         extra_A = max(0, T - len(A))\n#         extra_B = max(0, T - len(B))\n#         same = len(C)\n#         have = 0\n#         take = min(same, extra_A); same -= take; have += take\n#         take = min(same, extra_B); same -= take; have += take\n#         return min(len(A), T) + min(len(B), T) + have\n\n# class Solution:\n#     def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n#         N = len(A)\n#         T = N // 2\n#         A = set(A)\n#         B = set(B)\n#         A, B, C = A - B, B - A, A & B\n#         have = 0\n#         same = len(C)\n#         give = lambda A: max(0, T - len(A))\n#         take = min(same, give(A)); same -= take; have += take\n#         take = min(same, give(B)); same -= take; have += take\n#         return min(len(A), T) + min(len(B), T) + have\n\nclass Solution:\n    def maximumSetSize(self, A: List[int], B: List[int]) -> int:\n        N = len(A)\n        T = N // 2\n        A = set(A)\n        B = set(B)\n        A, B, C = A - B, B - A, A & B\n        a, b, c = min(len(A), T), min(len(B), T), len(C)\n        return min(a + b + c, N)\n```
[]