經典的算法面試題(1)

題目:


給定一個整數數組 nums,編寫一個算法將所有的0移到數組的末尾,同時保持非零元素的相對順序。
示例:
輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]
注意:必須在原數組上操作,不能拷貝額外的數組。盡量減少操作次數。
這個問題考察候選人處理數組的能力,以及他們編寫高效、優雅代碼的能力。在解決問題時,請考慮如何避免不必要的元素移動。

思路:

1、雙指針法:
使用兩個指針,一個用來遍歷數組(遍歷指針),另一個指向最新發現的非零元素應當存放的位置(非零指針)。
當遍歷指針指向的值不為0時,將其與非零指針指向的值交換,然后非零指針前移。
通過整個數組的遍歷,所有非零元素都被推向數組的開頭,而0都被留在了數組的末尾。
2、計數零元素法:
首先遍歷一次數組,統計出0的個數。
在第二次遍歷期間,使用一個新的索引(比如 insertPos),它基于0的計數從數組開頭開始移動。
如果遍歷到非零元素,就將它放到insertPos的位置,并將insertPos向前移動。
遍歷完成后,按照統計出的0的個數,在數組末尾補上0。
3、移動非零元素法:
遍歷數組,一旦遇到非0數,就將其移到數組最前方現有非0數的后面。
記錄最后一個非0數的位置。
在數組剩余的部分填充0。


每種方法都有其特點,但雙指針法在空間和操作復雜度上通常是最優的。這個方法只需要( O(n) )的時間復雜度和( O(1) )的額外空間復雜度。

時間復雜度


1. **雙指針法**:時間復雜度為 ( O(n) ),因為只需要遍歷一遍數組,n 為數組長度。
2. **計數零元素法**:時間復雜度為 ( O(n) ),即便需要兩次遍歷(一次計數0的個數,一次移動非零元素),但兩次遍歷的時間復雜度都是線性的。
3. **移動非零元素法**:時間復雜度也為 ( O(n) ),一次線性遍歷即可完成所有非零元素的移動和0的填充。
值得注意的是,盡管所有方法的時間復雜度都是線性的,但實際執行時間可能會因為常數因子和元素實際移動次數的差異而有所不同。在決定使用哪一種方法時,這也是需要考慮的因素之一。

實現代碼

1、雙指針法

#include <stdio.h>
void moveZeroes(int* nums, int numsSize) {int j = 0; // 指向當前非0元素應該插入的位置for (int i = 0; i < numsSize; ++i) {if (nums[i] != 0) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;j++;}}
}

2、計數零元素法:

#include <stdio.h>
void moveZeroes(int* nums, int numsSize) {int zeroCount = 0; // 計算數組中0的個數for (int i = 0; i < numsSize; i++) {if (nums[i] == 0) {zeroCount++;}}int index = 0;for (int i = 0; i < numsSize; i++) {if (nums[i] != 0) {nums[index++] = nums[i];}}for (int i = index; i < numsSize; i++) {nums[i] = 0;}
}

3、移動非零元素法:

#include <stdio.h>
void moveZeroes(int* nums, int numsSize) {int insertPos = 0; // 指向當前已處理數組的末尾for (int i = 0; i < numsSize; i++) {if (nums[i] != 0) {nums[insertPos++] = nums[i];}}while (insertPos < numsSize) {nums[insertPos++] = 0;}
}

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

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

相關文章

數據處理——一維數組轉列向量(分割時間序列為數據塊時的問題)

記錄在處理數據時被磕絆了一下的一個處理細節。 1.想要達到的要求 在某次滑動窗口取樣時間序列數據時&#xff0c;我得到如下一個以一維數組為元素的列表&#xff1a; 對于如上輸出列表中的每個一維數組&#xff0c;我希望將其轉換為下圖中的形式&#xff0c;簡單說就是希望他…

編程筆記 Golang基礎 042 文件處理

編程筆記 Golang基礎 042 文件處理 一、文件處理二、Go語言文件處理創建文件和寫入內容打開文件并按模式讀寫讀取文件內容更高級的文件和IO操作改變文件權限目錄操作 小結 一、文件處理 文件處理是指在計算機科學中&#xff0c;對存儲在磁盤或其他持久性存儲介質上的文件進行的…

Android Jni添加打印(C++打印)

Android Jni添加打印&#xff08;C打印&#xff09; 文章目錄 Android Jni添加打印&#xff08;C打印&#xff09;一、前言二、添加日志實現1、在某個類上面定義類型和方法2、把日志方法定義在.h文件中定義 myLog.h3、引用打印頭文件的示例代碼&#xff08;1&#xff09; MainA…

【詳識JAVA語言】面向對象程序三大特性之三:多態

多態 多態的概念 多態的概念&#xff1a;通俗來說&#xff0c;就是多種形態&#xff0c;具體點就是去完成某個行為&#xff0c;當不同的對象去完成時會產生出不同的狀態。 多態實現條件 在java中要實現多態&#xff0c;必須要滿足如下幾個條件&#xff0c;缺一不可&#xf…

循環隊列與循環雙端隊列

文章目錄 前言循環隊列循環雙端隊列 前言 1、學習循環隊列和循環雙端隊列能加深我們對隊列的理解&#xff0c;提高我們的編程能力。 2、本文循環隊列使用的是數組&#xff0c;循環雙端隊列用的是雙向鏈表 3、題目連接&#xff1a;設計循環隊列 &#xff0c;設計循環雙端隊列。 …

【機器學習】有監督學習算法之:支持向量機

支持向量機 1、引言2、決策樹2.1 定義2.2 原理2.3 實現方式2.4 算法公式2.5 代碼示例 3、總結 1、引言 小屌絲&#xff1a;魚哥&#xff0c;泡澡啊。 小魚&#xff1a;不去 小屌絲&#xff1a;… 此話當真&#xff1f; 小魚&#xff1a;此話不假 小屌絲&#xff1a;到底去還是…

Linux 網絡接口的混雜模式(Promiscuous mode)認知

寫在前面 博文內容為 混雜模式的簡單認知理解不足小伙伴幫忙指正 認定一件事&#xff0c;即使拿十分力氣都無法完成&#xff0c;也要拿出十二分力氣去努力。 —《劍來》 網絡接口的混雜模式 混雜模式(Promiscuous mode)&#xff0c;簡稱 Promisc mode&#xff0c;俗稱監聽模式…

什么是支持向量機(Support vector machine)和其原理

作為機器學習的基礎算法&#xff0c;SVM被反復提及&#xff0c;西瓜書、wiki都能查到詳細介紹&#xff0c;但是總是覺得還差那么點&#xff0c;于是決定自己總結一下。 一、什么是SVM&#xff1f; 1、解決什么問題&#xff1f; SVM&#xff0c;最原始的版本是用于最簡單的線…

藍橋杯備賽第五篇(動態規劃)

1.數位dp public class Main {static long[] limit;static int length;static long[][] dp;public static long dfs(int pos, int pre, boolean flag, boolean lead) {if (pos length) return 1;if (!flag && !lead && dp[pos][pre] ! -1) return dp[pos][pr…

總結 HashTable, HashMap, ConcurrentHashMap 之間的區別

1.多線程環境使用哈希表 HashMap 不行,線程不安全 更靠譜的,Hashtable,在關鍵方法上加了synchronized 后來標準庫又引入了一個更好的解決方案;ConcurrentHashMap 2.HashMap 首先HashMap本身線程不安全其次HashMap的key值可以為空&#xff08;當key為空時&#xff0c;哈希會…

【Java數據結構】——五道算法題讓你靈活運用Map和Set

目錄 一.只出現一次的數字 二.寶石與石頭 三.舊鍵盤 四.給定一個數組&#xff0c;統計每個元素出現的次數 五.前K個高頻單詞 一.只出現一次的數字 136. 只出現一次的數字 - 力扣&#xff08;LeetCode&#xff09; 算法原理&#xff1a;我們將nums中每個元素都存入到set中…

C/C++嵌入式開發環境搭建,Qt交叉編譯,cmake交叉編譯,clion/vscode遠程開發

目錄 交叉編譯簡介cmake 交叉編譯clion 交叉編譯vscode 遠程嵌入式開發Qt交叉編譯1.安裝交叉編譯工具2.交叉編譯qt庫3.將交叉編譯的Qt庫復制到板子上4.安裝和配置 Qt Creator&#xff0c;支持交叉編譯5.QT嵌入式開發6.QT嵌入式開發報錯解決QIconvCodec::convertToUnicode: usin…

ASUS華碩天選5筆記本電腦FX607JV原裝出廠Win11系統下載

ASUS TUF Gaming F16 FX607JV天選五原廠Windows11系統 適用型號&#xff1a; FX607JU、FX607JI、FX607JV、 FX607JIR、FX607JVR、FX607JUR 下載鏈接&#xff1a;https://pan.baidu.com/s/1l963wqxT0q1Idr98ACzynQ?pwd0d46 提取碼&#xff1a;0d46 原廠系統自帶所有驅動、…

TypeScript中 “ <> “ 語法 和 “ : “ 怎么使用

在 TypeScript 中&#xff0c;尖括號語法(<Type>)和as關鍵字(value as Type)都是用于類型斷言&#xff0c;而冒號(:)用于類型注解。這三種語法在不同的場景下使用&#xff1a; 尖括號語法和as關鍵字&#xff1a; 尖括號語法(<Type>value)&#xff1a; 這種語法在…

[LeetBook]【學習日記】鏈表反轉

來源于「Krahets」的《圖解算法數據結構》 https://leetcode.cn/leetbook/detail/illustration-of-algorithm/ 鏈表反轉的遞歸要點 遞歸終止條件為當前節點為空&#xff0c;表明遍歷到了鏈表尾部遞歸函數傳入參數為當前節點的下一個節點按照是否重新開辟存儲空間分類下面只寫…

python自動化學習--3.8python操作EXCEL文件python日志收集處理

1、Excel文件處理 安裝 openpxl 第三方庫 openpxl 模塊三大組件: 1、工作簿 &#xff08;包含多個sheet工作表&#xff09; 2、工作表 &#xff08;某個數據包含在某個工作表&#xff09; 3、單元格 1、創建excel工作簿 import openpyxl"""Excel表格的創建…

【簡說八股】Spring事務失效可能是哪些原因?

Spring事務介紹 Spring事務是指在Spring框架中對數據庫操作進行管理的一種機制&#xff0c;它確保一組數據庫操作要么完全執行成功&#xff08;提交&#xff09;&#xff0c;要么完全不執行&#xff08;回滾&#xff09;&#xff0c;從而保持數據一致性和完整性。 Spring框架…

GotoXy控制臺光標的位置更新

光標控制解釋 控制臺的光標更新方法, 用于控制數據輸出位置 void gotoXY(int x, int y)//新函數&#xff1a;更新光標 {COORD c;c.X x;c.Y y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); }代碼解釋 這段代碼定義了一個名為 gotoXY 的函數&#xff0c;…

設計模式-裝飾者模式應用實踐

裝飾者模式&#xff08;Decorator Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許動態地向一個現有的對象添加新的功能&#xff0c;同時不改變其結構。這種模式通過創建一個裝飾類來包裝原有的類&#xff0c;提供額外的行為。 下面是一個使用 Java 實現裝飾者模式…

【Spring Boot】實現全局異常處理

1.定義基礎異常接口類 /*** description: 服務接口類* author: MrVK* date: 2021/4/19 21:39*/ public interface BaseErrorInfoInterface {/*** 錯誤碼* return*/String getResultCode();/*** 錯誤描述* return*/String getResultMsg(); } 2.定義錯誤處理枚舉類 /*** desc…