LeetCode 第464場周賽 第三天

1. 3658 奇數和與偶數和的最大公約數(歐幾里得)

鏈接:題目鏈接
題解

題解時間復雜度O(logmin(a, b))

  1. 獲得前n個奇、偶數的總和,由于數列為等差數列,等差數列和公式:(a1 + an) * n / 2),可以快速求和。
  2. 獲取兩個數字的最大公約數,用歐幾里得算法可求得最大公約數,代碼模版如下。

代碼

    class Solution {public int gcd(int a, int b) {return b != 0 ? gcd(b, a % b) : a;}public int gcdOfOddEvenSums(int n) {// 等差數列求和int sum1 = (1 + 2 * n - 1) * n / 2;int sum2 = (2 + 2 * n) * n / 2;return gcd(sum1, sum2);}
}

2. 3659 數組元素分組(抽屜原理)

鏈接:題目鏈接
題解

題解時間復雜度O(n):

  1. nums 中的每個元素必須被分配到恰好一個組中,每個組恰好k個不同的元素,說明 n * k = 數組長度,n為具體組數。
  2. 組數 = 數組長度 / k,如果某個數字重復次數 > 組數,那么肯定沒辦法滿足每個組恰好k個不同的元素(抽屜原理),反之均可滿足。

代碼

class Solution {public boolean partitionArray(int[] nums, int k) {int len = nums.length;if (len % k != 0) {return false;}int countLimit = len / k;Map<Integer, Integer> numCountMap = new HashMap<>();for (int num: nums) {numCountMap.put(num, numCountMap.getOrDefault(num, 0) + 1);}return numCountMap.values().stream().noneMatch(numCount -> numCount > countLimit);}
}

3. 3660 跳躍游戲 9(預處理 單調棧 二分解法)

鏈接:題目鏈接
題解

背景:僅當 nums[j] < nums[i] 時,才允許跳躍到下標 j,其中 j > i。 僅當 nums[j] > nums[i] 時,才允許跳躍到下標 j,其中 j < i。(一次跳躍中,往前跳,nums值必須嚴格大于; 往后跳,nums值必須嚴格小于);
題解時間復雜度O(nlogn)

  1. 對于第i個元素,如果能到達的最大值在左側,那么一次跳躍即可(需要維護左側最大值)。
  2. 對于第i個元素,如果能到達的最大值在右側,首先往右跳躍到j位置,nums[j] < nums[i]的,所以nums[j]肯定不是i元素能到達的最大值,意味著還得從j下標往左跳,才有可能 num[j] > nums[i]。
  3. 注意:對于第i個元素,最大值在右側還有一種跳躍方式。可能存在[30, 10, 35, 22] 這種情況,對于nums[1]來說,并不能直接跳到35去(因為nums[2、3] > nums[1]),但是有一條路線可以達到nums[3](1 -> 0 -> 3 -> 2),(第2、3點)總結:對于最大值在右側情況,nums[i]可以先跳到左側最大值(nums[j] >= nums[i]),再往右側跳(覆蓋的范圍更廣)
  4. 因為要在logn級別找到 i右邊元素到達的最大值,那么很自然想到了維護一個有序的列表,通過二分方式在logn時間復雜度找到右側能到達的最大值。這里維護有序列表有個關鍵點:如果 2能到達x,3能達到x-1或者x,那么這個列表還有必要維護3這個元素嗎?答案是不需要將3這個元素入隊(因為能到達2的元素包含了能到達3的元素 且 3能到達的最大值<=2能到達的最大值),也就是單調棧思想
  5. 有序列表樣例:[1 -> 10, 2 -> 12, 5 -> 15],此時有序是指的nums[i]是遞增的,且nums[i]能找到的最大值也是遞增的。所以在二分查找的時候只需要找到小于nums[i]的第一個元素,再拿到它對應的最大值即可。
  6. 第i個元素能到達的最大值 = max(左側最大值, 右側最大值)

代碼

 class Solution {public int[] maxValue(int[] nums) {int len = nums.length;int[] leftMaxValues = new int[len];int maxValue = 0;for (int i = 0; i < len; ++ i) {maxValue = Math.max(maxValue, nums[i]);leftMaxValues[i] = maxValue;}int[] result = new int[len];TreeMap<Integer, Integer> map = new TreeMap<>();// 初始化result[len - 1] = leftMaxValues[len - 1];map.put(nums[len - 1], leftMaxValues[len - 1]);for (int i = len - 2; i >= 0; -- i) {// 獲取右邊最大值Map.Entry<Integer, Integer> entry = map.lowerEntry(leftMaxValues[i]);if (entry != null) {result[i] = entry.getValue();} else {result[i] = leftMaxValues[i];}// 維護mapInteger old = map.get(nums[i]);if (old == null || old < result[i]) {map.put(nums[i], result[i]);// 刪除所有 "比nums[i]大,且 value <= result[0]" 的節點while (true) {Map.Entry<Integer, Integer> higher = map.higherEntry(nums[i]);if (higher != null && higher.getValue() <= result[i]) {map.remove(higher.getKey());} else break;}}}return result;}}

4. 3661 可以被機器人摧毀的最大墻壁數目(DP解法)

鏈接:題目鏈接
題解

題解 時間復雜度O(nlogn)

  1. 因為機器人會阻擋子彈的穿透,所以第i個機器人,最多穿透[i - 1, i + 1]下標的區域,那么也以為著第i個機器人只與第i-1、i+1個機器人有關系
  2. robot、distance 為一組信息 walls為一組信息,兩組信息分別排序(機器人跟相鄰機器人有關系 所以需要排序處理)
  3. 這里機器人只能往左往右發射,可以用f[i][j] i表示第i個機器人 j表示往左還是右設計 j為0 往左 j為1往右
  4. dp轉移方程式: f[i][1] = Math.max(f[i - 1][0], f[i - 1][1]) + i機器人往右打多少個墻; f[i][0] = Math.max(f[i - 1][0], f[i - 1][1]) + i機器人往左打多少個墻
  5. 打多少個墻?可以拿到機器人射擊區間,因為墻列表也做了排序(是有序的),再通過二分計算能射擊多少個墻
  6. 注意1:這里要注意i-1機器人往右,i機器人往左射擊的情況,對射的情況(避免重復計算墻
  7. 注意2:這里要考慮機器人與墻重合的情況,比如i機器人與墻重合,但是i-1機器人往右射擊 計算了該墻,但是i機器人射擊又計算該墻的情況(又重復計算了),所以墻與機器人重合情況,該墻只讓該機器人射擊。(i-1機器人往右射擊,區間從[nums[i-1], nums[i]] -> [nums[i-1], nums[i] -1))

代碼

class Solution {class Pair implements Comparable<Pair>{private int robotIndex;private int distance;@Overridepublic int compareTo(Pair pair) {return robotIndex - pair.robotIndex;}public Pair(int robotIndex, int distance) {this.robotIndex = robotIndex;this.distance = distance;}}public int maxWalls(int[] robots, int[] distance, int[] walls) {int len = robots.length;List<Pair> pairs = new ArrayList<>(len);for (int i = 0; i < len; ++ i) {pairs.add(new Pair(robots[i], distance[i]));}Collections.sort(pairs);Arrays.sort(walls);int[][] f = new int[len + 1][2];for (int i = 1; i <= len; ++ i) {if (i == 1) {f[i][1] = caclSum(0, pairs, pairs.get(0).distance, walls, false, true);f[i][0] = caclSum(0, pairs, pairs.get(0).distance, walls, true, true);} else {f[i][1] = Math.max(f[i - 1][0], f[i - 1][1]) + caclSum(i - 1, pairs, pairs.get(i - 1).distance, walls, false, true);Pair pair = pairs.get(i - 1);Pair prePair = pairs.get(i - 2);if (pair.distance + prePair.distance >= pair.robotIndex - prePair.robotIndex) {f[i][0] = Math.max(f[i - 1][0] + caclSum(i - 1, pairs, pair.distance, walls, true, true), Math.max(f[i][0], Math.max(f[i - 2][0], f[i - 2][1]) + caclSum(i - 2, pairs, pair.distance + prePair.distance, walls, false, false)));} else {f[i][0] = Math.max(f[i - 1][1], f[i - 1][0]) + caclSum(i - 1, pairs, pair.distance, walls, true, true);}}}return Math.max(f[len][0], f[len][1]);}public int caclSum(int index, List<Pair> pairs, int distance, int[] walls, boolean left, boolean excludeNextIndex) {int l, r;if (left) {r = pairs.get(index).robotIndex;l = r - distance;if (index - 1 >= 0) {l = Math.max(l, pairs.get(index - 1).robotIndex + (excludeNextIndex ? 1 : 0));}} else {l = pairs.get(index).robotIndex;r = l + distance;if (index + 1 < pairs.size()) {r = Math.min(r, pairs.get(index + 1).robotIndex - (excludeNextIndex ? 1 : 0));}}int wallLIndex, wallRIndex;// 找到大于等于l的第一個下標int wallL = 0, wallR = walls.length - 1;while (wallL < wallR) {int mid = (wallL + wallR) >> 1;if (walls[mid] >= l) {wallR = mid;} else {wallL = mid + 1;}}wallLIndex = wallL;// 找到小于等于R的第一個下標wallL = 0;wallR = walls.length - 1;while (wallL < wallR) {int mid = (wallL + wallR + 1) >> 1;if (walls[mid] <= r) {wallL = mid;} else {wallR = mid - 1;}}wallRIndex = wallL;if (wallLIndex <= wallRIndex && walls[wallLIndex] >= l && walls[wallRIndex] <= r) {return wallRIndex - wallLIndex + 1;}return 0;}
}

如果對你有幫助,辛苦點個贊,謝謝啦,朋友!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94462.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94462.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94462.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IntelliJ IDEA 集成 ApiFox 操作與注解規范指南

一、IDEA裝入Apifox 1.安裝Apifox Helper 說明:在 IntelliJ IDEA 中安裝 ApiFox Helper 插件。 2.打開Apifox 說明:點擊 設置,在菜單中選擇 API訪問令牌。在彈出的窗口中輸入任意名稱,并選擇令牌的有效期(為了方便,我這里選擇了 無期限)。生成令牌后,由于 令牌只能復…

C++---雙指針

在C編程中&#xff0c;雙指針算法是一種高效的解題思路&#xff0c;其核心是通過設置兩個指針&#xff08;或索引&#xff09;遍歷數據結構&#xff08;如數組、鏈表、字符串等&#xff09;&#xff0c;利用指針的移動規則減少無效操作&#xff0c;從而將時間復雜度從暴力解法的…

【LLM】GLM-4.5模型架構和原理

note 文章目錄note一、GLM-4.5模型二、Slime RL強化學習訓練架構Reference一、GLM-4.5模型 大模型進展&#xff0c;GLM-4.5技術報告,https://arxiv.org/pdf/2508.06471&#xff0c;https://github.com/zai-org/GLM-4.5&#xff0c;包括GLM-4.5&#xff08;355B總參數&#xff…

LLM 中增量解碼與模型推理解讀

在【LLM】LLM 中 token 簡介與 bert 實操解讀一文中對 LLM 基礎定義進行了介紹&#xff0c;本文會對 LLM 中增量解碼與模型推理進行解讀。 一、LLM 中增量解碼定義 增量解碼&#xff08;Incremental Decoding&#xff09;是指在自回歸文本生成過程中&#xff0c;模型每次只計…

1.Spring Boot:超越配置地獄,重塑Java開發體驗

目錄 一、Spring框架&#xff1a;偉大的基石 歷史背景與挑戰 Spring的革命性貢獻 新的挑戰&#xff1a;配置地獄 二、Spring Boot&#xff1a;約定大于配置的革命 四大核心特性 1. 快速創建獨立應用 2. 自動配置&#xff1a;智能化的魔法 3. 起步依賴&#xff1a;依賴管…

assert使用方法

assert 是 Python 中用來進行 調試 和 驗證 的一個關鍵字&#xff0c;它用于測試一個 條件表達式 是否為真。如果條件為假&#xff0c;assert 會拋出一個 AssertionError 異常&#xff0c;通常帶有錯誤信息。語法&#xff1a;assert condition, "Error message"condi…

【實習總結】快速上手Git:關鍵命令整理

目錄 git的四大工作區域 git首次配置 克隆遠程倉庫 提交代碼到遠程倉庫 查看文件狀態&#xff08;可選&#xff09; 添加文件到暫存區 將暫存區的內容提交到本地倉庫 將本地的提交上傳到遠程倉庫 拉取并合并代碼 第一種方式 第二種方式 分支管理 查看與創建分支 …

02-開發環境搭建與工具鏈

第2課&#xff1a;開發環境搭建與工具鏈 &#x1f4da; 課程目標 掌握DevEco Studio的下載、安裝和配置熟悉HMS Core&#xff08;華為移動服務&#xff09;的使用了解鴻蒙模擬器與真機調試環境掌握必備開發工具的使用 &#x1f6e0;? DevEco Studio環境搭建 2.1 下載與安裝…

刪掉一個元素以后全為1的最長子數組-滑動窗口

1493. 刪掉一個元素以后全為 1 的最長子數組 - 力扣&#xff08;LeetCode&#xff09; Solution #include<iostream> #include<vector> using namespace std;class Solution { public://滑動窗口//動態維護一個窗口&#xff0c;窗口內只能有1個0&#xff0c;記錄窗…

【計算機網絡 | 第8篇】編碼與調制

文章目錄通信系統中的編碼與調制&#xff1a;從信道基礎到信號傳輸技術一、信道與通信電路&#x1f342;二、三種基本通信方式&#x1f4d6;1. 單向通信&#xff08;單工通信&#xff09;2. 雙向交替通信&#xff08;半雙工通信&#xff09;3. 雙向同時通信&#xff08;全雙工通…

當AI遇上終端:Gemini CLI的技術魔法與架構奧秘

"代碼不僅僅是指令的集合&#xff0c;更是思想的載體。當AI與終端相遇&#xff0c;會碰撞出怎樣的火花&#xff1f;" 在這個AI技術日新月異的時代&#xff0c;Google推出的Gemini CLI無疑是一顆璀璨的明星。它不僅僅是一個命令行工具&#xff0c;更是一個將人工智能無…

ViLU: Learning Vision-Language Uncertainties for Failure Prediction

研究方向&#xff1a;Image Captioning1. 論文介紹本文提出ViLU&#xff08;Vision-Language Uncertainties&#xff09;&#xff0c;一個用于學習視覺語言不確定性量化&#xff08;UQ&#xff09;和檢測視覺語言模型故障的事后框架。使用VLMs進行量化&#xff08;UQ&#xff0…

數據集筆記:百度地圖高德地圖坐標互轉

1 為什么會有高德坐標系和百度坐標系&#xff1f;根據《測繪法》和國家保密法規&#xff0c;在中國大陸范圍內的地理坐標數據必須做加密處理&#xff0c;不允許直接使用 WGS84&#xff08;openstreetmap&#xff09;所以出現了GCJ-02 和 BD-09高德、騰訊、谷歌中國都遵循 GCJ-0…

SkyWalking高效線程上下文管理機制:確保調用鏈中traceId來自同一個請求

SkyWalking Agent 能確保獲取到“正確”的 traceId,其核心在于它建立并維護了一套高效的線程上下文管理機制。這套機制確保了即使在復雜的多線程、異步環境下,也能將正確的上下文(包含 traceId)與當前正在執行的代碼邏輯關聯起來。 其工作原理可以概括為下圖所示的流程: …

Kafka-Eagle安裝

目錄Eagle環境安裝Mysql環境準備Kafka環境準備Eagle安裝Kafka-Eagle框架可以監控Kafka集群的整體運行情況&#xff0c;在生產環境中經常使用 Eagle環境安裝 Mysql環境準備 Eagle的安裝依賴于Mysql&#xff0c;Mysql主要用來存儲可視化展示的數據 將mysql文件夾及里面所有內…

Matlab系列(005) 一 歸一化

目錄1、前言2、什么是歸一化&#xff1f;3、為什么要進行歸一化4、歸一化方法詳解與Matlab實現5、總結1、前言 ? ??歸一化技術是數據預處理的核心環節&#xff0c;本文將深度解析主流歸一化方法&#xff0c;提供可復現Matlab代碼&#xff0c;并探討其在各領域中的應用場景。…

【K8s】整體認識K8s之namespace

命名空間將資源劃分為相互隔離的組。kubectl get namespace/ns系統默認創建四個namespace&#xff0c;分別是default、kube-node-lease、kube-public、kube-system。default 沒有指明使用其它命名空間的對象所使用的默認命名空間、kube-system 系統創建對象所使用的命名空間。…

rust語言 (1.88) egui (0.32.1) 學習筆記(逐行注釋)(十八) 使用表格

使用表格egui_extras::TableBuilder // Cargo.toml [dependencies] eframe "0.32.1" egui "0.32.1" egui_extras "0.32.1"egui_extras::Column::auto() 列寬根據內容自動計算.resizable(true) 允許用戶手動拖動調整列寬 fn main() -> efra…

【C#】構造函數實用場景總結

文章目錄前言一、構造函數是什么&#xff1f;二、構造函數的用法1.初始化對象&#xff0c;避免無效狀態2 初始化靜態成員3 構造函數重載4.構造函數鏈5. 單例模式&#xff0c;多次實例化保持一個對象6. 依賴注入7. 初始化只讀對象前言 構造函數是我們平常編程里經常能碰到的老伙…

LLM預訓練架構全解析:從零構建一個語言世界的“操作系統”

導讀&#xff1a;作為開發者&#xff0c;我們每天都在import或#include各種庫&#xff0c;我們信任這些由無數代碼構成的底層依賴。那么&#xff0c;當我們調用一個LLM時&#xff0c;它所依賴的那個更底層的、無形的**“語言操作系統”**&#xff0c;又是如何被“編譯”出來的&…