← 返回博客列表
Uber

🚨 Uber 2026 OA 真題全解析:二進位位操作 + 單調堆疊 + 子陣列排列 + 數字交換配對 —— 22 分鐘 4 題 AC!

2026-01-20

製造焦慮:打破幻覺

最近衝了 Uber 2026 OA,平台依舊是 CodeSignal,題量 4 道題,70 分鐘完成。

說實話,這次題目對於有一定基礎的同學來說,熟悉度很高,我自己花了 22 分鐘就全部做完。四題裡有兩個題幾乎是白送的,看一眼就能寫出來,完全沒有難度。

為了幫助大家提前練手,我把每道題的思路和做法都整理出來了。


Uber 2026 OA 面試概覽

項目 詳情
平台 CodeSignal
題量 4 道
時間 70 分鐘
難度 中等偏上,但部分題目熟悉即可快速完成

考察點

總體來說,Uber OA 更看重邏輯清晰度、思路正確性和實現速度,演算法難度不是很大,但細節處理容易出錯。


Q1: Minimum Operations to Reduce Binary Number to Zero

🔍 題目描述

給定一個正整數 n,每次操作可以加或減 2^i(i ≥ 0),求將 n 變為 0 的最少操作次數

📝 解題思路

  1. 將問題看作二進位處理
  2. 從低位到高位處理每一位,同時維護進位
  3. 當前位值 = 原位值 + 進位
    • 若值為 1:可以直接減法消掉,操作數 +1,或者加法產生進位
    • 若值為 2(位 1 + 進位 1):直接進位,不增加操作
  4. 累加操作數
  5. 最終進位為 0 時結束

💡 關鍵洞察

🧑‍💻 程式碼實現

def min_operations_to_zero(n: int) -> int:
    """
    Uber OA 真題:二進位數變為 0 的最少操作次數
    
    Args:
        n: 正整數
    
    Returns:
        int: 最少操作次數
    """
    operations = 0
    carry = 0
    
    while n > 0 or carry > 0:
        # 當前位的值 = 原位值 + 進位
        current_bit = (n & 1) + carry
        
        if current_bit == 1:
            # 值為 1:需要一次操作(加或減)
            # 貪心:如果下一位也是 1,選擇加法(產生進位,可能合併連續 1)
            next_bit = (n >> 1) & 1
            if next_bit == 1:
                # 加法:產生進位
                carry = 1
            else:
                # 減法:不產生進位
                carry = 0
            operations += 1
        elif current_bit == 2:
            # 值為 2:直接進位,不增加操作
            carry = 1
        else:
            # 值為 0:無需操作
            carry = 0
        
        n >>= 1
    
    return operations


# 測試用例
print(min_operations_to_zero(7))   # 7 = 111 -> +1 = 1000 -> -8 = 0, 答案: 2
print(min_operations_to_zero(5))   # 5 = 101 -> -4 = 1 -> -1 = 0, 答案: 2
print(min_operations_to_zero(1))   # 1 = 1 -> -1 = 0, 答案: 1
print(min_operations_to_zero(15))  # 15 = 1111 -> +1 = 10000 -> -16 = 0, 答案: 2
print(min_operations_to_zero(10))  # 10 = 1010 -> -8 = 2 -> -2 = 0, 答案: 2

⚠️ 小技巧


Q2: Discounted Price Sum

🔍 題目描述

每個物品售價 = 原價 − 右邊第一個 ≤ 當前價格的物品的價格(若無則按原價出售)。

總售價按原價出售物品的索引

📝 解題思路

  1. 從右向左遍歷物品
  2. 使用單調遞增堆疊尋找右邊第一個 ≤ 當前價格的物品
  3. 堆疊空 ⇒ 原價出售,記錄索引
  4. 堆疊非空 ⇒ 售價 = 原價 − 堆疊頂價格
  5. 累加總售價
  6. 輸出總售價及原價出售的物品索引(升序)

🧑‍💻 程式碼實現

def discounted_price_sum(prices: list) -> tuple:
    """
    Uber OA 真題:折扣價格總和
    
    Args:
        prices: 物品原價列表
    
    Returns:
        tuple: (總售價, 原價出售的索引列表)
    """
    n = len(prices)
    total = 0
    full_price_indices = []
    stack = []  # 單調遞增堆疊,存儲 (價格, 索引)
    
    # 從右向左遍歷
    for i in range(n - 1, -1, -1):
        current_price = prices[i]
        
        # 彈出所有大於當前價格的元素
        while stack and stack[-1][0] > current_price:
            stack.pop()
        
        if not stack:
            # 堆疊空:原價出售
            total += current_price
            full_price_indices.append(i)
        else:
            # 堆疊非空:折扣價 = 原價 - 右邊第一個 ≤ 當前價格的物品價格
            discount_price = current_price - stack[-1][0]
            total += discount_price
        
        # 當前元素入堆疊
        stack.append((current_price, i))
    
    # 索引升序排列
    full_price_indices.sort()
    
    return total, full_price_indices


# 測試用例
prices1 = [8, 4, 6, 2, 3]
print(discounted_price_sum(prices1))
# 分析:
# i=4: 3, 堆疊空, 原價 3
# i=3: 2, 堆疊空, 原價 2
# i=2: 6, 堆疊頂 2 ≤ 6, 售價 6-2=4
# i=1: 4, 堆疊頂 2 ≤ 4, 售價 4-2=2
# i=0: 8, 堆疊頂 4 ≤ 8, 售價 8-4=4
# 總價: 4+2+4+2+3 = 15, 原價索引: [3, 4]

prices2 = [5, 1, 4, 2]
print(discounted_price_sum(prices2))

⚠️ 小技巧


Q3: Balanced Subarray

🔍 題目描述

對於每個 k(1 ~ n),判斷是否存在一個子陣列恰好是 1 ~ k 的排列

📝 解題思路

  1. 先記錄每個數字在排列中的位置 pos[value]
  2. k = 1 開始,維護包含數字 1 ~ k 的最小位置區間 [L, R]
    • L = min(pos[1..k])
    • R = max(pos[1..k])
  3. 如果 R − L + 1 == k,則 k 是 balanced
    • 區間長度恰好等於 k,且值域為 1 ~ k,必為排列
  4. 否則不是 balanced

🧑‍💻 程式碼實現

def balanced_subarray(arr: list) -> list:
    """
    Uber OA 真題:判斷 1~k 是否存在 balanced 子陣列
    
    Args:
        arr: 1~n 的排列
    
    Returns:
        list: 長度為 n 的布林陣列,result[i] 表示 k=i+1 是否 balanced
    """
    n = len(arr)
    
    # 記錄每個數字的位置(1-indexed value -> 0-indexed position)
    pos = [0] * (n + 1)
    for i, val in enumerate(arr):
        pos[val] = i
    
    result = []
    min_pos = float('inf')
    max_pos = float('-inf')
    
    for k in range(1, n + 1):
        # 更新包含 1~k 的區間範圍
        min_pos = min(min_pos, pos[k])
        max_pos = max(max_pos, pos[k])
        
        # 判斷區間長度是否恰好為 k
        interval_len = max_pos - min_pos + 1
        if interval_len == k:
            result.append(True)
        else:
            result.append(False)
    
    return result


# 測試用例
arr1 = [3, 1, 2, 5, 4]
print(balanced_subarray(arr1))
# k=1: pos[1]=1, 區間[1,1], len=1 ✓
# k=2: pos[2]=2, 區間[1,2], len=2 ✓
# k=3: pos[3]=0, 區間[0,2], len=3 ✓
# k=4: pos[4]=4, 區間[0,4], len=5 ≠ 4 ✗
# k=5: pos[5]=3, 區間[0,4], len=5 ✓
# 輸出: [True, True, True, False, True]

arr2 = [2, 1, 4, 3]
print(balanced_subarray(arr2))
# k=1: pos[1]=1, 區間[1,1], len=1 ✓
# k=2: pos[2]=0, 區間[0,1], len=2 ✓
# k=3: pos[3]=3, 區間[0,3], len=4 ≠ 3 ✗
# k=4: pos[4]=2, 區間[0,3], len=4 ✓
# 輸出: [True, True, False, True]

⚠️ 小技巧


Q4: Maximum Pairs by Swapping Digits

🔍 題目描述

兩個數字若可透過最多兩次交換某些位置的數字變成彼此(含相等),算作一對。求總對數

📝 解題思路

  1. 長度不同 ⇒ 不可能配對
  2. 長度相同
    • 將數字轉為字串並排序字元
    • 若排序後相同 ⇒ 可透過若干次交換變成彼此(計數)
    • 若排序後不同
      • 統計不同位置的字元
      • 若不同位置數 ≤ 4 且字元可兩兩匹配 ⇒ 可兩次交換
  3. 實現步驟
    • 先按長度分組
    • 組內用雜湊表統計排序串頻次計算相等對數
    • 對不等情況檢查是否符合兩次交換條件

🧑‍💻 程式碼實現

from collections import defaultdict

def max_pairs_by_swapping(nums: list) -> int:
    """
    Uber OA 真題:最多兩次交換配對數
    
    Args:
        nums: 數字列表
    
    Returns:
        int: 可配對的總對數
    """
    # 按長度分組
    length_groups = defaultdict(list)
    for num in nums:
        s = str(num)
        length_groups[len(s)].append(s)
    
    total_pairs = 0
    
    for length, group in length_groups.items():
        n = len(group)
        
        # 統計排序後相同的字串(可透過交換變成彼此)
        sorted_count = defaultdict(int)
        for s in group:
            sorted_s = ''.join(sorted(s))
            sorted_count[sorted_s] += 1
        
        # 計算同排序串的配對數:C(count, 2) = count * (count - 1) / 2
        for count in sorted_count.values():
            total_pairs += count * (count - 1) // 2
    
    return total_pairs


def can_match_with_two_swaps(s1: str, s2: str) -> bool:
    """
    檢查兩個字串是否可以透過最多兩次交換變成彼此
    """
    if len(s1) != len(s2):
        return False
    
    # 找出不同位置
    diff_positions = []
    for i in range(len(s1)):
        if s1[i] != s2[i]:
            diff_positions.append(i)
    
    # 0 個不同:已相等
    if len(diff_positions) == 0:
        return True
    
    # 2 個不同:一次交換
    if len(diff_positions) == 2:
        i, j = diff_positions
        return s1[i] == s2[j] and s1[j] == s2[i]
    
    # 4 個不同:兩次交換(需要檢查字元是否匹配)
    if len(diff_positions) == 4:
        chars1 = [s1[i] for i in diff_positions]
        chars2 = [s2[i] for i in diff_positions]
        return sorted(chars1) == sorted(chars2)
    
    return False


# 更精確的版本(考慮不同位置的交換)
def max_pairs_precise(nums: list) -> int:
    """
    精確版本:檢查每對是否可透過最多兩次交換配對
    """
    n = len(nums)
    pairs = 0
    
    for i in range(n):
        for j in range(i + 1, n):
            s1, s2 = str(nums[i]), str(nums[j])
            if can_match_with_two_swaps(s1, s2):
                pairs += 1
    
    return pairs


# 測試用例
nums1 = [123, 321, 132, 456]
print(max_pairs_by_swapping(nums1))  # 123, 321, 132 可互相配對,共 3 對

nums2 = [111, 111, 111]
print(max_pairs_by_swapping(nums2))  # 3 個相同,C(3,2) = 3 對

nums3 = [12, 21, 34, 43, 56]
print(max_pairs_by_swapping(nums3))  # (12,21), (34,43) = 2 對

⚠️ 小技巧


複雜度分析

題目 時間複雜度 空間複雜度
Q1: Binary to Zero O(log n) O(1)
Q2: Discounted Price O(n) O(n)
Q3: Balanced Subarray O(n) O(n)
Q4: Max Pairs O(n² × L) 或 O(n × L log L) O(n × L)

其中 L = 數字的最大位數


🔥 為什麼大多數人會掛?

常見錯誤 正確做法
Q1 忘記處理進位 維護 carry 變數
Q1 從高位開始處理 必須從低位向高位遍歷
Q2 單調堆疊方向錯誤 從右向左遍歷
Q2 索引沒排序 輸出前升序排列
Q3 重複掃描求 min/max 累積更新 min_pos, max_pos
Q4 只考慮相等情況 還要考慮 2 次和 4 次不同位置

FAQ | Uber 2026 OA 常見問題

Q1: Uber 2026 OA 有幾道題?難度如何?

Uber 2026 OA 一共有 4 道題,題型包括二進位加減最少操作數、單調堆疊折扣售價、子陣列排列判斷和數字最多交換匹配對數。難度偏中等偏上,但大部分題型屬於常見模板題型,只要熟悉 CodeSignal 平台和 Python 解題思路,通常可以快速完成。

Q2: 完成 Uber 2026 OA 大概需要多長時間?

根據實戰經驗,如果熟悉題型,四題可以在 20–30 分鐘內完成全部操作。我自己整套題花了 22 分鐘就一次過,透過合理規劃題目順序和使用 Python 模板程式碼,可以顯著節省時間。

Q3: Uber 2026 OA 有哪些考察重點?

主要考察以下能力:

此外,還會考察邊界條件處理、演算法複雜度理解和程式碼實現能力

Q4: Python 在 Uber OA 中有哪些優勢?

Python 語法簡潔,內建資料結構(如字典、列表、集合)和函數(如 min, max, sorted)非常適合處理 OA 題目邏輯,尤其是:

合理使用 Python 模板程式碼,可以提高完成速度和正確率。

Q5: 有沒有快速通過 Uber OA 的經驗技巧?

經驗總結如下:

Q6: Uber OA 的題目會重複嗎?

根據實戰經驗,CodeSignal 平台上的題目類型重複率較高,尤其是類似二進位操作、單調堆疊和子陣列排列的經典模板題型。提前練習這些題型,理解通用解法和邊界處理方法,可以大幅提高 AC 準確率。


📞 oavoservice 服務

別再浪費時間!Uber / TikTok / Stripe OA 快速通關指南。

很多同學其實不是不會寫,而是 OA 時間壓力太大、容易在細節上翻車

針對這種情況,我們提供成熟的大廠 OA 支援方案:


👉 立即添加微信:Coding0201

不要讓 4 道 OA 題,毀掉你的 Uber Offer。


本文由 oavoservice 團隊原創,轉載請註明出處。