LeetCode - 28 找出字符串中第一個匹配項的下標

題目來源

28. 找出字符串中第一個匹配項的下標 - 力扣(LeetCode)

題目解析

暴力解法

本題如果采用暴力解法的話,可以定義兩個指針 i,j,其中 i 指針用于掃描 S(haystack)串,j 指針用于掃描 T(needle)串。

比如:S = "aabaabaaf",T = "aabaaf"

假設 S 串的起始匹配位置為 k,則 k 取值范圍是:[0, s.length - t.length]

上圖匹配過程中,分為兩個循環:

外層循環,即匹配的輪數控制,或者說是,S串的匹配起始位置控制,比如:

  • 第 0 輪,T 串是從 S 串的 0 索引位置開始匹配
  • 第 1 輪,T 串是從 S 串的 1 索引位置開始匹配
  • ...
  • 第 k 輪,T 串是從 S 串的 k 索引位置開始匹配

內層循環,即T串和S串的 k ~ k + t.length 范圍進行逐個字符一一匹配,

  • 如果發現存在對應位的字符不一致,則說明當前輪匹配失敗,直接進入下一輪
  • 如果所有位置上的字符都相同,則說明匹配成功,即在S中找到了和T相同的子串,且該子串起始位置是k

假設,s.length = n,t.length = m,則暴力解法的時間復雜度為O(n * m)

KMP算法

對于字符串模式匹配問題,暴力算法并非最優解決方案,雖然 s,t 都是隨機串,但是這些隨機串也會存在一定規律可以利用。

比如上面暴力解法圖示中,當第 k = 0 輪匹配失敗后,第 k =1 輪,第 k =2 輪是否注定失敗了呢?

如下圖是第 k = 0 輪最后一個字符匹配失敗的情況:

我們觀察其中匹配成功的部分,即"aabaa"部分,這部分具有相同前后綴aa

如果我們將 S,T 的?"aabaa" 后面部分抽象化(....),如下圖所示,那么:

  • 第 k = 0 輪匹配失敗是因為 “抽象部分(....)” 的匹配失敗

  • 第 k = 1 輪,第 k = 2 輪匹配失敗,其實就是 "aabaa" 部分的匹配失敗:

?我們將第 k = 1 輪,第 k = 2 輪,第 k = 3 輪再次簡化一下,如下圖所示:

那么是不是很顯然可以發現,第1輪,第2輪是注定失敗的。

我們再舉一個例子:

如果上面 S,T 在第 k = 0 輪因為抽象部分(...)匹配失敗,那么下一輪,其實是否可以直接讓:前綴部分直接跳轉到后綴位置

因為前綴部分(如abc)和后綴部分(如abc)完全相同,而前綴部分(如abc)和中間部分(如d)不相同,因此前綴部分(如abc)和中間部分對齊(如d)時,必然匹配失敗。

這樣的話,是不是跳過了兩輪匹配,即節省了兩輪匹配的時間。

請大家再思考一下,上面讓前綴部分直接跳轉和后綴部分對齊,真的是只節省兩輪匹配的過程嗎?

下面圖示是,第0輪匹配失敗后,直接跳到對稱部分開始重新匹配

如果對應到暴力解法過程的話,那么下面畫X的部分就都是跳過的過程

我們再觀察下這個跳到對稱部分的過程中,i,j指針的變化

可以發現,i 指針在 S 中的位置并沒有改變

  • j 指針回退指向到了 T 的 "aabaa" 前綴部分(aa)的后一個位置(b所在位置)
  • 或者假設前綴部分(aa)長度為 len,則 j 回退到 T 串的 len 索引位置

那么上面這個改進算法的時間復雜度是多少呢?

由于上面算法中,保證了 i 指針不會回退,因此時間復雜度只有O(n)。

而這個算法其實就是KMP算法。

前綴表概念

上面我們已經說明了KMP算法的大致原理,其中最關鍵的就是在模式串 T 中找其前綴子串的最長相同前后綴,比如

T = "aabaaf" 有前綴子串 "aabaa",該子串的最長相同前后綴是 "aa"

那么該如何通過代碼來實現這個功能呢?

KMP算法的三個創始人K,M,P提出了前綴表的概念。

首先定義下字符串的前綴、后綴概念

假設字符串 t 長度為n,那么:

  • 前綴就是起始索引必須為0,結束索引<n-1的所有子串
  • 后綴就是結束索引必須為n-1,起始索引必須>0的所有子串

因此

  • 前綴和后綴不能是字符串 t 本身
  • 字符串 t 的前綴和后綴是可能存在重疊部分的

我們舉一個例子,比如列出T的子串 "aabaa" 的所有的前綴和后綴

長度前綴(紅色子串)后綴(綠色子串)
1aabaaaabaa
2aabaaaabaa
3aabaaaabaa
4aabaaaabaa

其中最長且相同的前后綴是"aa"。

注意,判斷前綴和后綴是否相同,都是從左往右逐一比對,因此上面例子中,長度為3的前綴"aab"和后綴"baa"是不相同的。

還有相同的前綴、后綴是可能存在重疊

比如字符串 "ababab"

長度前綴(紅色子串)后綴(綠色子串)
1abababababab
2abababababab
3abababababab
4abababababab
5abababababab

最長相同的前綴和后綴是"abab"?,他們是存在重疊的

因此T = "aabaaf"所有前綴子串的最長相同的前綴和后綴的長度分別為:

T的前綴串最長相同的前后綴最長相同的前后綴的長度
a""0
aaa1
aab""0
aabaa1
aabaaaa2
aabaaf""0

我們將 T 的所有前綴串對應的 “最長相同的前后綴的長度” 記錄為一個數組 next,我們稱 next 為前綴表

next = [0, 1, 0, 1, 2, 0]

    前綴表的應用

    前面我們手算出了前綴表 next 數組

    next = [0, 1, 0, 1, 2, 0]

    next[j] 表示:T 的 [0, j]?范圍子串的最長相同前后綴長度,比如:

    • next[0] 表示:T的 [0,0] 范圍子串 "a"? ? ? ? ? 的最長相同前后綴長度 0
    • next[1] 表示:T的 [0,1] 范圍子串 "aa"? ? ? ? 的最長相同前后綴長度 1
    • next[2] 表示:T的 [0,2] 范圍子串 "aab"? ? ? 的最長相同前后綴長度 0
    • next[3] 表示:T的 [0,3] 范圍子串 "aaba"? ? 的最長相同前后綴長度 1
    • next[4] 表示:T的 [0,4] 范圍子串 "aabaa"? 的最長相同前后綴長度 2
    • next[5] 表示:T的 [0,5] 范圍子串 "aabaaf" 的最長相同前后綴長度 0

    那么如何將 next 應用到KMP算法中呢?

    比如下圖中,S[i] != T[j] 時,我們前面分析過,需要做如下動作:

    • i 指針保持指向不變
    • j 指針回退到 T 的 len 索引位置(len:表示 T 的前綴串 "aabaa" 的最長相同前后綴 "aa" 的長度)

    len 含義和 next[j-1] 含義是相同的

    • next[j - 1] 表示 T 的 [0, j-1] 范圍子串 "aabaa" 的最長相同前后綴的長度?

    因此,當s[i] != t[j] 時,我們可以讓: j = next[ j - 1 ]

    另外,如果 j = 0 時就匹配不上,此時 next[j-1] 會發生越界異常,因此針對這種i情況,我們應該特殊處理,如下圖所示,就是一個 j = 0無法匹配的情況:

    此時,我們應該讓 i++,j 保持不變,繼續匹配

    這其實和前面KMP算法規定的 i 指針不回退這一條件不沖突。因為上面過程 i 指針沒有發生回退。

    生成前綴表

    前面我們已經手算過了前綴表,但是手算過程是一個暴力枚舉的過程。

    關于前綴表的生成,我們可以利用動態規劃求解。

    比如:假設已知 K = NEXT[J-1],現在要求 NEXT[J],比如下圖

    如果 T[J] == T[K] 的話,比如

    NEXT[J] 表示 [0, J] 范圍子串 "abdabeabdabe" 的最長相同前后綴("abdabe")長度為 K+1

    因此當 T[J] == T[K] 時,那么 NEXT[J]? = K + 1

    如果T[J] ! = T[K]的話,比如

    那么此時該如何求解 NEXT[J] 呢?

    我們將上圖繼續分解

    如果下面兩個位置的字符相同

    那么此時就找到了 NEXT[J] 的值。

    因此當 T[J] != T[K] 時,我們可以讓 K = NEXT[K-1],繼續前面邏輯,直到 K 移動到:

    • T[J] == T[K] 時,此時 NEXT[J] = K + 1
    • 若 K == 0 時,依舊 T[J] != T[K],則此時可以認為 NEXT[J] = 0,此時我們J++,求解下一個 NEXT[J]

    C算法源碼

    暴力解法
    int strStr(char* s, char* t) {int sLen = strlen(s);int tLen = strlen(t);for (int k = 0; k <= sLen - tLen; k++) {int i = k;int j = 0;while (j < tLen && s[i] == t[j]) {i++;j++;}if (j == tLen) {return k;}}return -1;
    }
    KMP算法
    int* getNext(char* t) {int tLen = strlen(t);int* next = (int*)calloc(tLen, sizeof(int));int j = 1;int k = next[j - 1];while (j < tLen) {if (t[j] == t[k]) {next[j] = k + 1; // 前綴范圍 t[0,k] == 后綴范圍 t[j-k,j]  此時最長相同前后綴長度為:k+1j++;k++;} else if (k > 0) {k = next[k - 1]; // 若 t[j] != t[k] && k > 0,則縮短前綴部分,k = next[k-1] 后繼續比較 t[k] 和 t[j]} else {j++; // 若 t[j] != t[k] && k == 0,則 k 無法繼續后退,此時可以認為 next[j] 為 0,進行j++,繼續求解下一個next[j]}}return next;
    }int strStr(char* s, char* t) {int sLen = strlen(s);int tLen = strlen(t);int* next = getNext(t); // 生成 t 串的前綴表int i = 0;int j = 0;while (i < sLen && j < tLen) {if (s[i] == t[j]) {i++;j++;} else if (j > 0) {j = next[j - 1]; // 若 s[i] != t[j] && j > 0,則 i 指針不動,j 指針回退到 t 串的 next[j-1] 位置 } else {i++; // 若 s[i] != t[j] && j == 0,則表示 s[i] 和 t[0] 首個字符就匹配失敗,我們只能進入下一輪,即 i++}}if (j == tLen) { // 若 t 串所有字符都被匹配成功,則 j == t.lengthreturn i - j; // 此時 s 串的 i - j 位置就是首次匹配 t 的子串起始位置} else {return -1;}
    }

    C++算法源碼

    暴力解法
    class Solution {
    public:int strStr(string s, string t) {int sLen = s.size();int tLen = t.size();for (int k = 0; k <= sLen - tLen; k++) {int i = k;int j = 0;while (j < tLen && s[i] == t[j]) {i++;j++;}if (j == tLen) {return k;}}return -1;}
    };
    KMP算法
    class Solution {
    public:int strStr(string s, string t) {vector<int> next = getNext(t); // 生成 t 串的前綴表int i = 0;int j = 0;while (i < s.size() && j < t.size()) {if (s[i] == t[j]) {i++;j++;} else if (j > 0) {j = next[j - 1]; // 若 s[i] != t[j] && j > 0,則 i 指針不動,j 指針回退到 t 串的 next[j-1] 位置 } else {i++; // 若 s[i] != t[j] && j == 0,則表示 s[i] 和 t[0] 首個字符就匹配失敗,我們只能進入下一輪,即 i++}}if (j == t.size()) { // 若 t 串所有字符都被匹配成功,則 j == t.lengthreturn i - j; // 此時 s 串的 i - j 位置就是首次匹配 t 的子串起始位置} else {return -1;}}vector<int> getNext(string t) {vector<int> next(t.size(), 0);int j = 1;int k = next[j - 1];while (j < t.size()) {if (t[j] == t[k]) {next[j] = k + 1;  // 前綴范圍 t[0,k] == 后綴范圍 t[j-k,j]  此時最長相同前后綴長度為:k+1j++;k++;} else if (k > 0) {k = next[k - 1]; // 若 t[j] != t[k] && k > 0,則縮短前綴部分,k = next[k-1] 后繼續比較 t[k] 和 t[j]} else {j++; // 若 t[j] != t[k] && k == 0,則 k 無法繼續后退,此時可以認為 next[j] 為 0,進行j++,繼續求解下一個next[j]}}return next;}
    };

    Java算法源碼

    暴力解法
    
    class Solution {public int strStr(String haystack, String needle) {char[] s = haystack.toCharArray();char[] t = needle.toCharArray();for (int k = 0; k <= s.length - t.length; k++) {int i = k;int j = 0;while (j < t.length && s[i] == t[j]) {i++;j++;}if (j == t.length) {return k;}}return -1;}
    }
    KMP算法
    
    class Solution {public int strStr(String haystack, String needle) {char[] s = haystack.toCharArray();char[] t = needle.toCharArray();int[] next = getNext(t); // 生成 t 串的前綴表int i = 0;int j = 0;while (i < s.length && j < t.length) {if (s[i] == t[j]) {i++;j++;} else if (j > 0) { // 若 s[i] != t[j] && j > 0,則 i 指針不動,j 指針回退到 t 串的 next[j-1] 位置 j = next[j - 1];} else { // 若 s[i] != t[j] && j == 0,則表示 s[i] 和 t[0] 首個字符就匹配失敗,我們只能進入下一輪,即 i++i++;}}if (j == t.length) { // 若 t 串所有字符都被匹配成功,則 j == t.lengthreturn i - j; // 此時 s 串的 i - j 位置就是首次匹配 t 的子串起始位置} else {return -1;}}public static int[] getNext(char[] t) {int[] next = new int[t.length];int j = 1;int k = next[j-1];while (j < t.length) {if (t[j] == t[k]) {next[j] = k + 1; // 前綴范圍 t[0,k] == 后綴范圍 t[j-k,j]  此時最長相同前后綴長度為:k+1j++;k++;} else if (k > 0) { // 若 t[j] != t[k] && k > 0,則縮短前綴部分,k = next[k-1] 后繼續比較 t[k] 和 t[j]k = next[k - 1];} else {j++; // 若 t[j] != t[k] && k == 0,則 k 無法繼續后退,此時可以認為 next[j] 為 0,進行j++,繼續求解下一個next[j]}}return next;}
    }

    Python算法源碼

    暴力解法
    class Solution(object):def strStr(self, s, t):""":type haystack: str:type needle: str:rtype: int"""for k in range(0, len(s) - len(t) + 1):i = kj = 0while j < len(t) and s[i] == t[j]:i += 1j += 1if j == len(t):return kreturn -1
    KMP算法
    def getNext(t):next = [0] * len(t)j = 1k = next[j - 1]while j < len(t):if t[j] == t[k]:next[j] = k + 1  # 前綴范圍 t[0,k] == 后綴范圍 t[j-k,j]  此時最長相同前后綴長度為:k+1j += 1k += 1elif k > 0:k = next[k - 1]  # 若 t[j] != t[k] && k > 0,則縮短前綴部分,k = next[k-1] 后繼續比較 t[k] 和 t[j]else:j += 1  # 若 t[j] != t[k] && k == 0,則 k 無法繼續后退,此時可以認為 next[j] 為 0,進行j++,繼續求解下一個next[j]return nextclass Solution(object):def strStr(self, s, t):""":type haystack: str:type needle: str:rtype: int"""next = getNext(t)  # 生成 t 串的前綴表i, j = 0, 0while i < len(s) and j < len(t):if s[i] == t[j]:i += 1j += 1elif j > 0:j = next[j - 1]  # 若 s[i] != t[j] && j > 0,則 i 指針不動,j 指針回退到 t 串的 next[j-1] 位置 else:i += 1  # 若 s[i] != t[j] && j == 0,則表示 s[i] 和 t[0] 首個字符就匹配失敗,我們只能進入下一輪,即 i++if j == len(t):  # 若 t 串所有字符都被匹配成功,則 j == t.lengthreturn i - j  # 此時 s 串的 i - j 位置就是首次匹配 t 的子串起始位置else:return -1

    JavaScript算法源碼

    暴力解法
    /*** @param {string} haystack* @param {string} needle* @return {number}*/
    var strStr = function (s, t) {for (let k = 0; k <= s.length - t.length; k++) {let i = k;let j = 0;while (j < t.length && s[i] == t[j]) {i++;j++;}if (j == t.length) {return k;}}return -1;
    };
    KMP算法
    /*** @param {string} haystack* @param {string} needle* @return {number}*/
    var strStr = function (s, t) {const next = getNext(t); // 生成 t 串的前綴表let i = 0;let j = 0;while (i < s.length && j < t.length) {if (s[i] == t[j]) {i++;j++;} else if (j > 0) {j = next[j - 1]; // 若 s[i] != t[j] && j > 0,則 i 指針不動,j 指針回退到 t 串的 next[j-1] 位置} else {i++; // 若 s[i] != t[j] && j == 0,則表示 s[i] 和 t[0] 首個字符就匹配失敗,我們只能進入下一輪,即 i++}}if (j == t.length) { // 若 t 串所有字符都被匹配成功,則 j == t.lengthreturn i - j; // 此時 s 串的 i - j 位置就是首次匹配 t 的子串起始位置} else {return -1;}
    };var getNext = function (t) {const next = new Array(t.length).fill(0);let j = 1;let k = next[j - 1];while (j < t.length) {if (t[j] == t[k]) {next[j] = k + 1; // 前綴范圍 t[0,k] == 后綴范圍 t[j-k,j]  此時最長相同前后綴長度為:k+1j++;k++;} else if (k > 0) {k = next[k - 1]; // 若 t[j] != t[k] && k > 0,則縮短前綴部分,k = next[k-1] 后繼續比較 t[k] 和 t[j]} else {j++; // 若 t[j] != t[k] && k == 0,則 k 無法繼續后退,此時可以認為 next[j] 為 0,進行j++,繼續求解下一個next[j]}}return next;
    }

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

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

    相關文章

    Spring Boot 異步編程

    文章目錄 一、異步方法的使用1. 開啟異步支持2. 定義異步方法3. 調用異步方法踩坑記錄心得體會 二、線程池配置1. 自定義線程池2. 使用自定義線程池踩坑記錄心得體會 三、異步任務的監控與管理1. 日志記錄2. 異常處理3. 線程池監控踩坑記錄心得體會 在現代應用程序開發中&#…

    0.大模型開發知識點需求綜述

    文章目錄 一、機器學習與深度學習基礎二、自然語言處理&#xff08;NLP&#xff09;基礎三、大模型架構四、訓練優化技術五、數據處理與預處理六、分布式訓練與并行化策略七、微調方法與參數高效微調八、訓練框架、工具與自動化流程九、評估與部署十、前沿技術與未來趨勢 已更新…

    docker目錄掛載與卷映射的區別

    在 Docker 中&#xff0c;目錄掛載&#xff08;Bind Mount&#xff09;和卷映射&#xff08;Volume Mount&#xff09;的命令語法差異主要體現在路徑格式上&#xff0c;具體表現為是否以斜杠&#xff08;/&#xff09;開頭。以下是兩者的核心區別及使用場景的總結&#xff1a; …

    [Java基礎-線程篇]7_線程設計模式與總結

    摘要&#xff1a;懶漢單例模式怎么變得線程安全&#xff1f;Master-Worker歸并模式&#xff0c;工作竊取算法。Java線程相關源碼使用了什么設計模式&#xff1f; 資料引用&#xff1a;《Java高并發核心編程卷2》 目錄 線程安全的單例模式 Master-Worker模式 工作竊取算法 …

    在【k8s】中部署Jenkins的實踐指南

    &#x1f407;明明跟你說過&#xff1a;個人主頁 &#x1f3c5;個人專欄&#xff1a;《Kubernetes航線圖&#xff1a;從船長到K8s掌舵者》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目錄 一、引言 1、Jenkins簡介 2、k8s簡介 3、什么在…

    代碼隨想錄算法營Day59 | 尋找存在的路徑, 冗余連接,冗余連接II

    尋找存在的路徑 這題使用并查集即可。并查集加路徑壓縮。 #include <iostream> using namespace std; int find(int* father,int u){return father[u] u ? u : father[u] find(father,father[u]); }bool isSame(int* father,int u,int v){return find(father,u) fi…

    正則表達式(2)匹配規則

    正則表達式的匹配規則定義了如何識別字符串中的特定模式。這些規則包括字符類匹配、元字符匹配、數量詞、字符轉義和分組。 字符類匹配 字符類匹配允許你指定一個字符集合&#xff0c;并匹配該集合中的任意單個字符。這是通過方括號 [] 來實現的。 簡單字符類&#xff1a;[abc…

    【QWEN】機器人控制器的控制周期越短精度越高嗎

    好的&#xff0c;用戶問的是“機器人控制器的控制周期越短精度越高嗎”。我需要根據提供的知識庫內容來回答這個問題。首先&#xff0c;我得回憶一下知識庫里的相關信息。 知識庫里有幾篇相關的文章。比如&#xff0c;[3]提到控制周期越短&#xff0c;控制性能的上限越高&…

    [總概]Vue2/3React Diff算法

    根據搜索結果,大部分文檔都詳細描述了Vue的Diff算法原理、優化策略以及實現細節。例如,網頁1詳細介紹了Vue Diff算法的核心設計,包括雙端比較和key的作用;Vue3中的快速Diff算法; 通常,解釋一個算法可以從其基本原理、核心策略、優化手段、源碼實現以及應用場景等方面展開…

    【MySQL_03】數據庫基本--核心概念

    文章目錄 一、數據庫基礎1.1 數據庫基礎定義1.2 數據庫分類與典型產品1.3 數據庫模型1.4 數據庫層次結構1.5 數據庫核心機制1.6 數據表和視圖1.61 數據表&#xff08;Table&#xff09;1.62 視圖&#xff08;View&#xff09; 1.7 鍵類型1.8 MySQL數據類型1.9 數據庫范式化 二、…

    FreeRTOS第16篇:FreeRTOS鏈表實現細節04_為什么FreeRTOS選擇“侵入式鏈表”

    文/指尖動聽知識庫-星愿 文章為付費內容,商業行為,禁止私自轉載及抄襲,違者必究!!! 文章專欄:深入FreeRTOS內核:從原理到實戰的嵌入式開發指南 1 傳統鏈表 vs. 侵入式鏈表 在嵌入式系統中,內存和性能的優化至關重要。FreeRTOS選擇侵入式鏈表而非傳統鏈表,其背后是內…

    STM32讀寫片內FLASH 筆記

    文章目錄 前言STM32F105的內部ROM分布STM32F10x的閃存擦寫解鎖FPECMain FLASH 的編寫 main Flash的擦除注意點 前言 在通過OTA的方式對設備進行升級&#xff0c;若在使用內部FLASH裝載固件程序的方式下&#xff0c;需要擦寫 內部FLASH 從而實現把新的固件程序寫入到 內部FLASH…

    Python爬蟲實戰:爬取財金網實時財經信息

    注意:以下內容僅供技術研究,請遵守目標網站的robots.txt規定,控制請求頻率避免對目標服務器造成過大壓力! 一、引言 在當今數字化時代,互聯網數據呈爆炸式增長,其中蘊含著巨大的商業價值、研究價值和社會價值。從金融市場動態分析到行業趨勢研究,從輿情監測到學術信息收…

    3.3.2 用仿真圖實現點燈效果

    文章目錄 文章介紹Keil生成.hex代碼Proteus仿真圖中導入.hex代碼文件開始仿真 文章介紹 點燈之前需要準備好仿真圖keil代碼 仿真圖參考前文&#xff1a;3.3.2 Proteus第一個仿真圖 keil安裝參考前文&#xff1a;3.1.2 Keil4安裝教程 keil新建第一個項目參考前文&#xff1a;3.1…

    996引擎-問題處理:實現自定義道具變身卡

    996引擎-問題處理:實現自定義道具變身卡 方案一、修改角色外觀(武器、衣服、特效) 實現變身先看效果創建個NPC測試效果方案二、利用 Buff 實現變身創建:變身Buff配buff表,實現人物變形測試NPC創建道具:變身卡配item表,添加道具:變身卡觸發函數參考資料方案一、修改角色外…

    AI視頻領域的DeepSeek—阿里萬相2.1圖生視頻

    讓我們一同深入探索萬相 2.1 &#xff0c;本文不僅介紹其文生圖和文生視頻的使用秘籍&#xff0c;還將手把手教你如何利用它實現圖生視頻。 如下為生成的視頻效果&#xff08;我錄制的GIF動圖&#xff09; 如下為輸入的圖片 目錄 1.阿里巴巴全面開源旗下視頻生成模型萬相2.1模…

    驅動 AI 邊緣計算新時代!高性能 i.MX 95 應用平臺引領未來

    智慧浪潮崛起&#xff1a;AI與邊緣計算的時代 正悄然深植于我們的日常生活之中&#xff0c;無論是火熱的 ChatGPT 與 DeepSeek 語言模型&#xff0c;亦或是 Meta 智能眼鏡&#xff0c;AI 技術已經無形地影響著我們的生活。這股變革浪潮并未停歇&#xff0c;而是進一步催生了更高…

    如何快速判斷IP是否為代理

    1.探究IP地址的地理分布 代理IP的所在位置&#xff0c;往往與用戶實際所在地不吻合。可以通過運用WHOIS查詢工具或在線IP地址定位服務&#xff0c;輸入所需查詢的IP&#xff0c;即可獲得其地理位置信息。 若該信息顯示的位置并非用戶所在城市或顯示為知名代理服務器節點&…

    從CL1看生物計算機的創新突破與發展前景:技術、應用與挑戰的多維度剖析

    一、引言 1.1 研究背景與意義 隨著科技的飛速發展&#xff0c;計算機技術已經成為推動現代社會進步的核心力量之一。從最初的電子管計算機到如今的大規模集成電路計算機&#xff0c;計算機的性能得到了極大的提升&#xff0c;應用領域也不斷拓展。然而&#xff0c;傳統計算機…

    AI革命先鋒:DeepSeek與藍耘通義萬相2.1的無縫融合引領行業智能化變革

    云邊有個稻草人-CSDN博客 目錄 引言 一、什么是DeepSeek&#xff1f; 1.1 DeepSeek平臺概述 1.2 DeepSeek的核心功能與技術 二、藍耘通義萬相2.1概述 2.1 藍耘科技簡介 2.2 藍耘通義萬相2.1的功能與優勢 1. 全鏈條智能化解決方案 2. 強大的數據處理能力 3. 高效的模型…