代碼隨想錄算法訓練營|第三十天|93.复原IP地址、78.子集、90.子集II。刷题心得(c++)

5个4000比特大状态置换算法的设计与分析 下面是 5 个概念性、实验性的 4000 位可逆置换设计。它们都保证是双射,但未经过密码分析,不可直接用于生产系统。风格分别覆盖:三维 SPN、Feistel、可逆元胞自动机、ARX、宽轨迹/Keccak 式结构。 这 5 个设计分别代表了 SPN、Feistel、元胞自动机、ARX、宽轨迹 Keccak 五种不同风格,覆盖了主流大状态置换的构造思路。再次强调:它们只是实验性概念,若要用于实际协议,必须经过严格安全性分析。 阅读详情

目录

讀題

93.复原IP地址

自己看到题目的第一想法

看完代码随想录之后的想法

78.子集

自己看到题目的第一想法

90.子集II

自己看到题目的第一想法

93.复原IP地址 - 實作

思路

錯誤思路

正確思路

不使用path的思路

Code

錯誤思路

正確思路

不使用path的思路(代碼來源 代碼隨想錄)

78.子集 - 實作

思路

Code

90.子集II - 實作

思路

Used 錯誤思路

Used 正確思路

使用i 跳過相同元素 思路

Code

Used 錯誤思路

Used 正確思路

使用i 跳過相同元素 思路

總結

自己实现过程中遇到哪些困难

今日收获,记录一下自己的学习时长

相關資料

93.复原IP地址

78.子集

90.子集II


讀題

93.复原IP地址

自己看到题目的第一想法

  1. startIndex 是切割點
  2. startIndex, i 之間是切割點
  3. path大小為一 path[0] 可以是0,path大小大於1 path[0] ≠ 0
  4. ip 長度 需介於 0~255之間
  5. 建立函數判斷子字符串是否合法
  6. 最多切割四次

看完代码随想录之后的想法

看完之後,腦袋對於這道題目的想法清晰很多,自己的做法比較偏向是加一個path,而卡哥則是在原字串上進行操作,但兩種方法都實現出來了,一開始主要錯誤點在終止條件的錯誤設置,判斷Valid IP 的函數處理錯誤,以及回溯操作的錯誤,這幾個錯誤點導致我的程式無法正常值行,但整體的想法是有,但實際執行上在思考上自己有很多部分需要去釐清。

78.子集

自己看到题目的第一想法

在組合以及分割的時候都是有符合某個條件才收集結果,但在這一題當中可以想像就是每個節點收集結果,並且這個是一個集合,彼此不能相互干擾,需要使用startIndex 來進行控制

90.子集II

自己看到题目的第一想法

這題的第一個想法是其實就是跟組合總和II 一樣,需要進行去重,如果用卡哥的做法used 或者是跳過重複元素都可以蠻清楚的去解決這個問題

93.复原IP地址 - 實作

思路

錯誤思路

  1. 建立一個results 以及 path 儲存結果
  2. 回溯函數
    1. 傳入值 s, startIndex
    2. 終止條件
      1. startIndex大於s.size
      2. 如果startIndex大於s.size 代表已經找到一組切割方案,因為startIndex可以想像成切割線,如果切割線大於等於s的大小,代表已經沒有要切割的部分了
      3. 並且因為在單遞迴都有判斷是否為有效IP,所以如果到達終止條件的path裡的子字串都是有效IP
    3. 單遞迴
      1. i = startIndex; i < s.size() + 3 ; i++ 每個子字符串最多三個數
      2. 獲取startIndex 到 i 之間的區間→ 代表著s中的子串
      3. 判斷startIndex 到 i之間是否為有效IP
        1. 如果是,則將這個子串存入path
        2. 不是則跳過這次迴圈
  3. 判斷有效IP函數
    1. path大小為一 path[0] 可以是0,path大小大於1 path[0] ≠ 0
    2. ip 長度 需介於 0~255之間
  4. 主函式
    1. 傳入s以及0
    2. return results.

錯誤點:

  1. 終止條件設置錯誤,導致遞迴並未在深度為四的時候停止,而是繼續執行,新增pointSum來記錄目前的深度(已分割幾次),並對最後的字串進行判斷與處理
  2. for迴圈的終止條件設錯,有可能會讓startIndex超出i的範圍
  3. 回溯操作錯誤,導致path字串沒有正常回溯,改為紀錄原本的size,對path字串進行回溯操作
  4. 判斷Valid IP 函數中
    1. 未Filter s.size > 3 && < 1 的狀況
    2. 計算數值的部分,邊界條件設錯,應該是i ≥ 0 而不是 i > 0 這樣會少計算一次,導致錯誤結果

正確思路

  1. 建立一個results 以及 path 儲存結果
  2. 回溯函數
    1. 傳入值 s, startIndex, pointSum
    2. 終止條件
      1. pointSum == 3
      2. 如果pointSum == 3代表已經切割到第三次,代表已經沒有要切割的部分了
      3. 判斷最後的子字串是否Valid,如果有效則將結果放入results當中
    3. 單遞迴
      1. i = startIndex; i < s.size() ; i++
      2. 獲取startIndex 到 i 之間的區間→ 代表著s中的子串
      3. 紀錄目前的path大小 → 供字串回溯操作使用
      4. 判斷startIndex 到 i之間是否為有效IP
        1. 如果是,則將這個子串存入path,並加入’.’
        2. 不是則跳過這次迴圈
      5. 遞迴操作 backtracking(s, i + 1, pointSum + 1)
      6. 回溯操作 path.resize(oldSize)
  3. 判斷有效IP函數
    1. path大小為一 path[0] 可以是0,path大小大於1 path[0] ≠ 0
    2. path長度需介於 1 ~ 3 之
    3. ip 數值 需介於 0~255之間
  4. 主函式
    1. 傳入s, 0, 0
    2. return results.

不使用path的思路

  1. 建立一個results 儲存結果
  2. 回溯函數
    1. 傳入值 s, startIndex, pointSum
    2. 終止條件
      1. pointSum == 3
      2. 如果pointSum == 3代表已經切割到第三次,代表已經沒有要切割的部分了
      3. 判斷最後的子字串是否Valid,如果有效則將結果放入results當中
    3. 單遞迴
      1. i = startIndex; i < s.size() ; i++
      2. 判斷startIndex 到 i之間是否為有效IP
        1. 如果是
          1. 在切割點加入一個逗號
          2. 遞迴操作
          3. 回溯刪除逗號
        2. 不是則結束本層循環,因為假設當前的切割是 01.0.0.01 就算第一個切割點在往後仍然都不是合法的IP 數值。 → 剪枝操作
      3. 遞迴操作 backtracking(s, i + 1, pointSum + 1)
      4. 回溯操作 path.resize(oldSize)
  3. 判斷有效IP函數
    1. path大小為一 path[0] 可以是0,path大小大於1 path[0] ≠ 0
    2. path長度需介於 1 ~ 3 之
    3. ip 數值 需介於 0~255之間
    4. 非數字字符不合法
  4. 主函式
    1. 傳入s, 0, 0
    2. return results.

Code

錯誤思路

class Solution {
public:
    vector<string> results;
    string path;
    void backtracking(const string& s, int startIndex) {
        if(startIndex >= s.size()) {
            results.push_back(path);
            return;
        }

        for(int i = startIndex; i < startIndex + 3; i++) {
            string str = s.substr(startIndex, i - startIndex + 1);
            if(isValidIP(str)) {
                path += str;
                path += '.';
            } else {
                continue; 
            }
            backtracking(s, i + 1);
            path.pop_back();
        }
    }
     bool isValidIP(const string& s) {
        int count = 1;
        int sum = 0;
        if(s.size() != 1 && (s[0] - '0') == 0) return false;
        for (int i = s.size() - 1; i > 0; i--) {
            sum += (s[i] - '0') * count;
            count *= 10;
        }
        if(sum > 255 || sum < 0) return false;
        return true;
    }
    vector<string> restoreIpAddresses(string s) {
        backtracking(s, 0);
        return results;
    }
};

正確思路

class Solution {
public:
    vector<string> results;
    string path;
    void backtracking(const string& s, int startIndex, int pointSum) {
        if(pointSum == 3) {
            string str = s.substr(startIndex, s.size());
            if(isValidIP(str)) {
                results.push_back(path + str);
            }
            return;
        }

        for(int i = startIndex; i < s.size(); i++) {
            string str = s.substr(startIndex, i - startIndex + 1);
            int oldSize = path.size();
            if(isValidIP(str)) {
                path += str;
                path += '.';
            } else {
                continue; 
            }
            backtracking(s, i + 1, pointSum + 1);
            path.resize(oldSize);
        }
    }
     bool isValidIP(const string& s) {
			  int count = 1;
        int sum = 0;
        if(s.size() != 1 && (s[0] - '0') == 0 ) return false;
        if(s.size() > 3 || s.size() < 1) return false;
				for (int i = s.size() - 1; i >= 0; i--) {
            sum += (s[i] - '0') * count;
            count *= 10;
        }
        for (int i = 0; i < s.size(); i++) {
            sum = (s[i] - '0') + sum * 10;
        }
        if(sum > 255) return false;
        return true;
    }
    vector<string> restoreIpAddresses(string s) {
        backtracking(s, 0, 0);
        return results;
    }
};

不使用path的思路(代碼來源 代碼隨想錄)

class Solution {
private:
    vector<string> result;// 记录结果
    // startIndex: 搜索的起始位置,pointNum:添加逗点的数量
    void backtracking(string& s, int startIndex, int pointNum) {
        if (pointNum == 3) { // 逗点数量为3时,分隔结束
            // 判断第四段子字符串是否合法,如果合法就放进result中
            if (isValid(s, startIndex, s.size() - 1)) {
                result.push_back(s);
            }
            return;
        }
        for (int i = startIndex; i < s.size(); i++) {
            if (isValid(s, startIndex, i)) { // 判断 [startIndex,i] 这个区间的子串是否合法
                s.insert(s.begin() + i + 1 , '.');  // 在i的后面插入一个逗点
                backtracking(s, i + 2, pointNum + 1);   // 插入逗点之后下一个子串的起始位置为i+2
                s.erase(s.begin() + i + 1);         // 回溯删掉逗点
            } else break; // 不合法,直接结束本层循环
        }
    }
    // 判断字符串s在左闭又闭区间[start, end]所组成的数字是否合法
    bool isValid(const string& s, int start, int end) {
        if (start > end) {
            return false;
        }
        if (s[start] == '0' && start != end) { // 0开头的数字不合法
                return false;
        }
        int num = 0;
        for (int i = start; i <= end; i++) {
            if (s[i] > '9' || s[i] < '0') { // 遇到非数字字符不合法
                return false;
            }
            num = num * 10 + (s[i] - '0');
            if (num > 255) { // 如果大于255了不合法
                return false;
            }
        }
        return true;
    }
public:
    vector<string> restoreIpAddresses(string s) {
        result.clear();
        if (s.size() < 4 || s.size() > 12) return result; // 算是剪枝了
        backtracking(s, 0, 0);
        return result;
    }
};

78.子集 - 實作

思路

  1. 建立一個path 以及 results 收集結果
  2. 回溯函數 需傳入 nums 以及 startIndex
  3. 終止條件 if startIndex >= nums.size()
  4. 單遞迴
    1. I = startIndex I < nums.size() I ++
    2. path.push_back(nums[i])
    3. results.push_back(path)
    4. backtracking (nums, i + 1)
    5. path.pop_back()
  5. return

Code

class Solution {
public:
    vector<vector<int>> results;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex) {
        if(startIndex >= nums.size()) return;

        for(int i = startIndex; i < nums.size(); i++) {
            path.push_back(nums[i]);
            results.push_back(path);
            backtracking(nums, i + 1);
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> subsets(vector<int>& nums) {
        results.push_back(path);
        backtracking(nums, 0);
        return results;
    }
};

90.子集II - 實作

思路

Used 錯誤思路

  1. 建立一個path, results 數組儲存結果
  2. 回溯函數
    1. 傳入值 nums, startIndex, used
    2. 終止條件
      1. if startIndex ≥ nums.size()
    3. 單遞迴
      1. I = startIndex i < nums.size I ++
      2. if( i > 0 && nums[i] == nums[i-1] && used[i - 1] == false)
        1. continue;
      3. else
        1. path.push_back(nums[i])
        2. results.push_back(path)
      4. used[i] == true
      5. backtracking(nums, i + 1, used)
      6. used[i] == false
      7. path.pop_back()
    4. return
  3. 主函式
    1. created used
    2. backtracking
    3. Return results

錯誤點: 忘記排序

Used 正確思路

  1. 建立一個path, results 數組儲存結果
  2. 回溯函數
    1. 傳入值 nums, startIndex, used
    2. 終止條件
      1. if startIndex ≥ nums.size()
    3. 單遞迴
      1. I = startIndex i < nums.size I ++
      2. if( i > 0 && nums[i] == nums[i-1] && used[i - 1] == false)
        1. continue;
      3. else
        1. path.push_back(nums[i])
        2. results.push_back(path)
      4. used[i] == true
      5. backtracking(nums, i + 1, used)
      6. used[i] == false
      7. path.pop_back()
    4. return
  3. 主函式
    1. created used
    2. sort nums;
    3. backtracking
    4. Return results

使用i 跳過相同元素 思路

  1. 建立一個path, results 數組儲存結果
  2. 回溯函數
    1. 傳入值 nums, startIndex, used
    2. 終止條件
      1. if startIndex ≥ nums.size()
    3. 單遞迴
      1. I = startIndex i < nums.size I ++
      2. path.push_back(nums[i])
      3. results.push_back(path)
      4. backtracking(nums, i + 1, used)
      5. path.pop_back()
      6. while ( i + 1 < nums.size() && nums[i] == nums[i+1] ) i ++
    4. return
  3. 主函式
    1. sort nums;
    2. backtracking
    3. Return results

Code

Used 錯誤思路

class Solution {
public:
    vector<vector<int>> results;
    vector<int> path;
    
    void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {
        if(startIndex >= nums.size()) return;

        for(int i = startIndex; i < nums.size(); i++) {
            if(i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) continue;
            else {
                path.push_back(nums[i]);
                results.push_back(path);
            }
            used[i] = true;
            backtracking(nums, i + 1, used);
            used[i] = false;
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        vector<bool> used(nums.size(), false);
        results.push_back(path);
        backtracking(nums, 0, used);
        return results;      
    }
};

Used 正確思路

class Solution {
public:
    vector<vector<int>> results;
    vector<int> path;
    
    void backtracking(vector<int>& nums, int startIndex, vector<bool>& used) {
        if(startIndex >= nums.size()) return;

        for(int i = startIndex; i < nums.size(); i++) {
            if(i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) continue;
            else {
                path.push_back(nums[i]);
                results.push_back(path);
            }
            used[i] = true;
            backtracking(nums, i + 1, used);
            used[i] = false;
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        vector<bool> used(nums.size(), false);
        sort(nums.begin(), nums.end());
        results.push_back(path);
        backtracking(nums, 0, used);
        return results;      
    }
};

使用i 跳過相同元素 思路

class Solution {
public:
    vector<vector<int>> results;
    vector<int> path;
    
    void backtracking(vector<int>& nums, int startIndex) {
        if(startIndex >= nums.size()) return;

        for(int i = startIndex; i < nums.size(); i++) {
            path.push_back(nums[i]);
            results.push_back(path);
            backtracking(nums, i + 1);
            path.pop_back();
            while(i + 1 < nums.size() && nums[i] == nums[i + 1]) i++;
        }
        return;
    }
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        results.push_back(path);
        backtracking(nums, 0);
        return results;      
    }
};

總結

自己实现过程中遇到哪些困难

今天主要遇到的問題仍然是切割,在處理IP 的過程中,實作上沒有考慮清楚條件,導致各種問題產生。

但後續也通過代碼隨想錄的文字版以及卡哥的講解,慢慢釐清自己的錯誤點,並加已修正後就將問題解決了。

今日收获,记录一下自己的学习时长

今天大概學了2.5 hr , IP 大概佔了2hr ,另外兩題很直覺地寫出來了,但這兩個小時也讓我對切割的問題有比較深的理解,也有將我的錯誤點給列點出來,將問題點加以修正後,程式就沒有問題了

相關資料

93.复原IP地址

题目链接/文章讲解:https://programmercarl.com/0093.复原IP地址.html

视频讲解:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili

78.子集

题目链接/文章讲解:https://programmercarl.com/0078.子集.html

视频讲解:回溯算法解决子集问题,树上节点都是目标集和! | LeetCode:78.子集_哔哩哔哩_bilibili

90.子集II

题目链接/文章讲解:https://programmercarl.com/0090.子集II.html

视频讲解:回溯算法解决子集问题,如何去重?| LeetCode:90.子集II_哔哩哔哩_bilibili

别再问“这游戏啥引擎做的”了,手把手教你用SteamDB一键查询(附实战案例) 本文详细介绍了如何使用SteamDB一键查询游戏引擎信息,包括Unity 3D、Unreal Engine等热门引擎的识别方法。通过实战案例和高级查询技巧,帮助玩家快速获取游戏技术底细,优化游戏体验和兼容性分析。 阅读详情

相关推荐

保姆级教程:用AdGuard DNS代理实现全设备广告过滤(含Win/Mac/安卓/iOS配置)

本文提供了一份详尽的AdGuard DNS代理配置指南,帮助用户在全设备(Win/Mac/安卓/iOS)上实现广告过滤。通过系统级DNS设置,AdGuard能有效拦截广告、跟踪器和恶意网站,提升隐私保护和浏览效率。教程涵盖原理说明、各平台配置步骤及高级优化技巧,适合不同技术水平的用户。

weixin_42656416的博客 822

算法训练营day28(回溯算法04:复原IP地址,子集,子集2)

回溯算法04,字符串分割/节点收割/树层去重,加油!

weixin_61931006的博客 1053

【毕设】基于LoRa的物联网控制器:从原理图到PCB的完整硬件设计指南

本文提供了一份完整的基于LoRa的物联网控制器硬件设计指南,涵盖从系统框图、原理图设计到PCB布局布线的全流程。详细讲解了电源电路、单片机最小系统、信号接口以及LoRa无线模块等核心模块的设计要点与抗干扰技巧,并分享了实用的调试心得,旨在帮助电子、物联网专业学生顺利完成毕业设计,掌握低功耗远距离物联网节点的硬件开发实践。

weixin_42126677的博客 306

【代码随想录】【算法训练营】【第28天】 [93]复原IP地址 [78]子集 [90]子集II

思路及算法思维,指路。题目来自。day 28,工作的周二~

day day up 575

3GPP协议解读_物理层系列(一)_物理层协议怎么看?

5G NR相关协议一般都在38系列,点进去以后可以看到,38.2xx系列为物理层相关协议,为了掌握物理层相关知识,应该怎么看协议呢?我建议从38.201读起,对38.2xx系列协议有一个整体的把握。

JCMLSY的博客 1329

GMSL2摄像头接入避坑指南:从FMC子卡配置到V4L2调用的完整流程(附Ubuntu20.04实测)

本文详细解析了GMSL2摄像头接入的全流程,从FMC子卡配置到V4L2调用的完整指南。基于XC7Z100平台实测经验,提供了硬件选型、带宽优化、Linux驱动配置及高分辨率采集的实战技巧,帮助开发者规避常见问题,提升系统稳定性与性能。

weixin_33737774的博客 418

代码随想录算法训练营第二十四天| 93 复原IP地址 、78 子集、 90 子集II

继续坚持。

m0_53877706的博客 203

使用everything出现mem_virtual_alloc(): Fatal Error: out of memory解决方案

本文主要介绍了使用everything出现mem_virtual_alloc(): Fatal Error: out of memory解决方案,希望能对使用everything的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 1万+

代码随想录算法训练营day29|93.复原IP地址 78.子集 90.子集II

今天一早起来就开是看代码随想录,也是整了两个多小时才能搞定。

qq_63129511的博客 248

不使用工具箱,通过MATLAB纯编程实现lstm网络的训练过程

长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,是为了解决一般的RNN(循环神经网络)存在的长期依赖问题而专门设计出来的,所有的RNN都具有一种重复神经网络模块的链式形式。在标准RNN中,这个重复的结构模块只有一个非常简单的结构,例如一个tanh层。

平时工作较为繁忙,私信消息一般晚上回复,谢谢大家~~ 1013

高并发网络爬虫实践(欧赔、亚盘、大小指数数据爬取)

本文通过对一个实战化的高并发网络爬虫脚本进行深度模块化剖析,展示了如何构建一个兼具性能、健壮性和易用性的数据采集工具。核心设计思想总结模块化与单一职责: 每个函数都专注于解决一个特定问题,无论是网络请求、数据解析还是文件操作。并发与效率: 通过ThreadPoolExecutor实现了高效的并发抓取,极大缩短了总耗时。健壮性与容错: 强大的重试机制、细致的异常处理和线程安全的文件写入,保证了程序在复杂网络环境下的稳定运行。断点续传: 精心设计了进度记录与恢复机制,使得大规模抓取任务变得轻松可控。

猫敷雪 480

代码随想录-算法训练营day28【回溯算法04:复原IP地址、子集】

代码随想录-算法训练营day28【回溯算法04:复原IP地址、子集】

upward 347

金砖大赛-第二届网络安全防护治理实战技能大赛全国总决赛WP

格式进行md4加密,然后将小写的md4密文进行作为flag信息进行提交,提交格式为flag{MD4小写},例如调用频率异常高的user_id是user_xxx,使用的非公开模型名称是model-name,具体调用次数为10,那么按照格式,对user_xxx:model-name:10进行md4加密后,提交范例为:flag{dd00cb9e393f4a9ac639294b3cfe4d6a}挖矿木马是通过远程脚本进行部署的,请登录到失陷的服务器上,找到并分析挖矿木马是从那个远程IP下载的。

Laffrey的专栏 240

算法训练营 Day 24 - part03

因为 IP 地址被 3 个点分成 4 部分。

2301_80733560的博客 787

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

[算法训练营] 回溯算法专题(二)

本篇共5题,附有解题思路和AC代码。边听歌边刷起来吧~

进一步有一步的欢喜 240

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

@ 代码随想录算法训练营第5周(C语言)|Day28(回溯)

搞一个记录.位置的数组。不用写终止条件。宽度去重。

fu1034810010的博客 338

视频隐私脱敏工程化:CSRT/KCF追踪算法在本地推理中的实现与边界

在短视频内容合规审查中,动态遮挡(Dynamic Masking)是高频且高耗时的环节。传统手动关键帧打码不仅效率低下,且在目标快速移动或遮挡时极易出现遮罩漂移。本文从计算机视觉工程角度,解析基于CSRT与KCF算法的目标追踪方案在视频隐私处理中的技术路径、性能权衡及落地实践。

Mysssone的博客 212

【算法拾光】链表 哈希表|K个一组翻转链表 + 两数之和

K个一组翻转链表需分段反转,借助哑节点与前驱指针维护连接,避免断链;两数之和利用哈希表实现O(1)查找,空间换时间,高效定位目标组合。前者考察链表指针操作,后者聚焦映射关系构建,均为面试高频题。

wuqingyigexiaoba的博客 313

排序算法深度笔记(下):非比较类排序的线性突破与工程边界

排序算法时间复杂度额外空间复杂度稳定性是否基于比较选择排序O(N^2)(O(1))不稳定是冒泡排序O(N^2)(O(1))稳定是插入排序O(N^2)(O(1))稳定是归并排序O(N\log N)(O(N))稳定是快速排序O(N\log N)O(log N)不稳定是堆排序O(N\log N)O(1)不稳定是计数排序(O(N + M))O(M))稳定否基数排序O(N)稳定否桶排序平均O(N) / 最坏O(N^2)

2401_87069538的博客 571

算法日常・每日刷题--<动态规划>42

本题为“不相交的线”,与最长公共子序列问题相似。使用动态规划求解:定义 dp[i][j] 表示 nums1[0:i] 与 nums2[0:j] 的最大不相交连线数。若元素相等,则继承左上值加1;否则取上方或左方最大值。最终返回 dp[m][n],即两数组的最大不相交连线数。时间复杂度 O(mn),空间复杂度 O(mn)。

2503_92261635的博客 20

C语言程序设计题|有序数组插入数字冒泡排序

题目要求将一个数插入有序数组末尾,并用冒泡排序实现整体升序。代码先将输入数存入数组最后位置,再通过双重循环进行冒泡排序,每轮将较大元素向后移动,最终输出11个升序元素。该方法虽时间复杂度为O(n²),但符合题目要求,逻辑清晰,适合初学者理解排序原理。

2301_81429079的博客 749

【算法拾光】模拟|外观数列 + 数青蛙

本文总结两道模拟题解法:外观数列通过迭代统计连续数字个数生成下一项,关键在于处理末尾字符;数青蛙则模拟青蛙叫声“croak”状态转移,维护各阶段青蛙数量,记录最大并发数并确保全部完成。共性在于严格遵循流程、细致处理边界与非法情况,锻炼字符串遍历与状态管理能力。

wuqingyigexiaoba的博客 369

牛客周赛165C题(前后缀性质,递推,排序,枚举)

题目大意:给定长度为 `n` 的数组,选择 `k ∈ [1,n]`,将前 `k` 个元素整体翻转,后面的元素不变。要求操作后的整个数组非递减,统计满足条件的 `k` 的数量。题目链接:https://ac.nowcoder.com/acm/contest/141721/C。时间复杂度:O(nlogn)

2501_94316951的博客 170

408 算法 04|主元素与三元组最小距离:两种“扫描时做决定“的思路

2013(41) 的主元素用摩尔投票一遍选出候选,但真正的考点是"选完必须验票";2020(41) 的三元组最小距离,三指针每次只挪最小的那个,靠的是 D=2×(max−min) 这个恒等式。两套完整 C 代码加真实输出,附官方评分档位表。

m0_56226131的博客 408

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 85

算法61,判定是否为字符重排

两字符串能互为重排 ⇔。

sheshibenniaodan的博客 218

算法日常・每日刷题--<动态规划>32

给定严格递增的正整数数组,求最长斐波那契子序列长度。使用二维DP,dp[i][j]表示以arr[i]、arr[j]为最后两项的序列长度,初始化均为2。通过哈希表快速查找前一项target = arr[j] - arr[i],若存在且下标小于i,则状态转移:dp[i][j] = dp[k][i] + 1。遍历更新全局最大长度,最终若结果小于3则返回0。时间复杂度O(n²),空间复杂度O(n²)。

2503_92261635的博客 178
上一篇: 代碼隨想錄算法訓練營|第二十九天|39. 组合总和、40.组合总和II、131.分割回文串。刷题心得(c++)
下一篇: 代碼隨想錄算法訓練營|第三十一天|491.递增子序列、46.全排列、47.全排列 II。刷题心得(c++)
RVLIN
博客等级 码龄5年 104粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值