leetcode面試題 10.01. 合并排序的數組

在這里插入圖片描述

直接排序

直接使用Java已有的方法進行排序,這一招…大意了!

這題簡單,就是個基本的排序,后面難題,可能這只是一小步,內個時候直接用排序算法比較合適,這個不合適。。

class Solution {public void merge(int[] A, int m, int[] B, int n) {for(int i = 0; i < n; i++){A[m+i] = B[i];}Arrays.sort(A);}
}

我們看看方法
在這里插入圖片描述
這是一個更優的快速排序算法,對于某些數據,傳統的快速排序可能會退化為二次方的事件復雜度,而此算法會更快一些,是O(n log(n))。

這種方式,頂多算應用黑箱子,沒啥可以說的…

雙指針 + 臨時數組

我們可以對每個數組都添加一個索引指針,依次對比兩個數組的值,讓最小的進入臨時數組,比較之后,把剩余的數直接放入臨時數組,最后,臨時數組再賦值給A。

leetcode的動圖很好,直接放出來鏈接。

雙指針

class Solution {public void merge(int[] A, int m, int[] B, int n) {int[] temp = new int[m+n];int i = 0; // array A pointerint j = 0; // array B pointerint k = 0; // array temp pointerwhile(i < m && j < n){if(A[i] < B[j]){temp[k++] = A[i++];} else if(A[i] >= B[j]){temp[k++] = B[j++];} }// 剩余部分while(i < m){temp[k++] = A[i++];}while(j < n){temp[k++] = B[j++];}k = 0;i = 0;while(k < m + n){A[i++] = temp[k++];}}
}

這種方法,實現起來很簡單,其實就是依次比較,但是開辟新的數組,再放回去,就很麻煩。

同樣的思路,不同的實現方式

對于同樣的邏輯,代碼寫起來其實也不一定一樣的!我們看一看!

逆向雙指針

所以,我們嘗試一下在數組A直接動手腳,利用數組A中后半部分的剩余空間,看看可不可行!

關鍵點:A中的元素會不會被覆蓋

在這里插入圖片描述
我們可以,從兩數組的后面開始,比較誰大,將大的放進A的最后面。

在這里插入圖片描述
這里,我們列舉極端例子

  1. B中的元素,全部比A中最大的還大

那么,B中的元素全部放入A的剩余空間中去,顯然,沒有問題!

在這里插入圖片描述
2. B的元素,比A的元素都小

在這里插入圖片描述
當然也能放進去。

最后,我們看看中間狀態,也就是正常狀態

在這里插入圖片描述
很容易分析得出,不管怎么樣,A中的剩余空間一定夠用!

因此寫代碼實現:

class Solution {// 逆向雙指針public void merge(int[] A, int m, int[] B, int n) {int ap = m - 1;int bp = n - 1;int final_pointer = m + n - 1;while(ap >= 0 && bp >= 0){if(A[ap] > B[bp]){A[final_pointer--] = A[ap--];} else{A[final_pointer--] = B[bp--];}}// 若A剩余,就不用管了;若B剩余,都扔進去while(bp >= 0){A[final_pointer--] = B[bp--];}}
}

或者可以

class Solution {// 逆向雙指針public void merge(int[] A, int m, int[] B, int n) {int ap = m - 1;int bp = n - 1;int final_pointer = m + n - 1;while(bp >= 0){// 置換A的元素if(ap >= 0 && A[ap] > B[bp]){   // 注意順序不要寫反!A[final_pointer--] = A[ap--];} else {// 置換B的元素A[final_pointer--] = B[bp--];}}}
}

后者寫法簡潔一些,前者寫法更加明了,是繼承解法二的思想。

我們用嚴格的方式再說明一下A不會被覆蓋的問題

我們只需要滿足

  • A中可用的位置 >= (A已經置換的數量 + B已經置換的數量)

因此,我們分別表示一下

在這里插入圖片描述

我們要求的是白格子的數量,是

  • n - (pb + 1) = n - pb - 1
  • pb是索引,從0開始,因此,橙色一共pb + 1個,總數是n,減一下就行了

A同理

  • m - pa - 1

在這里插入圖片描述

當前數組A可插入數量應該是m + n - pa - 1

我們求的這三個數分別是(在同一時刻

  • f1:A扔到A后面去的
  • f2:B扔到A后面去的
  • f3:A后面總共可以插入的元素(不被覆蓋的情況下

我們只需要驗證f3 >= f1 + f2恒成立即可!

=> pa >= -1顯然恒成立。

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

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

相關文章

IA-32 Architecture: the function of segment regitster(CS DS SS ES)

對于IA-32架構&#xff0c;與8086不同&#xff0c;段寄存器不再是像以前一樣&#xff0c;直接作為段基址&#xff0c;因為32位的寄存器直接就可以表示4GB大小&#xff0c;不需要再偏移&#xff0c;因此段寄存器的含義也發生了相應的變化。 在IA-32架構里&#xff0c;段寄存器是…

x86異常處理與中斷機制(1)概述中斷的來源和處理方式

參考《計算機組成》&#xff08;北京大學 MOOC&#xff09; 1 異常與中斷的來源&#xff08;為什么需要中斷&#xff09; 首先&#xff0c;說明一下異常和中斷這兩個概念。 它們兩個唯一的區別&#xff0c;就是&#xff0c;沒有什么區別。只是不同的地方不同的時間不同的人的…

【C language】typedef的使用:結構體、基本數據類型、數組

typedef基本數據類型 typedef int a; a abc;后面的a abc就等價于int abc typedef結構體 typedef struct a {int a;int b; } abc;abc aaa;對于上述&#xff0c;abc aaa;就等價于struct a aaa; 簡而言之&#xff0c;typedef的本質&#xff0c;就是構建等價關系。 第一個例…

【C language】動態數組的創建和使用

在C語言中&#xff0c;使用malloc函數創建動態數組&#xff0c;使用一個指針指向它&#xff0c;使用下標進行訪問。 unsigned long *a (unsigned long *)malloc(2 * sizeof(int)); a[0] 1000; a[1] 2000; printf("%d %d\n", a[0], a[1]); free(a);上述例子&…

x86異常處理與中斷機制(2)中斷向量表

補充&#xff1a;事件不僅包含中斷和異常&#xff0c;還包含系統調用&#xff0c;這個屬于用戶主動請求的事件。 上一節&#xff0c;只有一個溢出異常&#xff0c;那么&#xff0c;如果很多異常、中斷呢&#xff1f;&#xff08;中斷向量表&#xff09; 另外&#xff0c;之前0…

x86異常處理與中斷機制(3)中斷處理過程

上一節講完了根據中斷類型號找中斷服務程序的過程&#xff0c;現在著重說明一下更加完整的中斷處理過程吧。 本節以8086時代的中斷處理過程為例進行說明&#xff0c;主要分兩大部分 硬件處理軟件處理 需要注意&#xff0c;這不是絕對的&#xff0c;得看實際情況&#xff0c;…

Linux 0.11 內核解析:中斷相關(1)asm.s文件中斷處理分析

0 源代碼 有兩個版本的&#xff0c;一個是帶中文注釋&#xff0c;Intel格式的&#xff1b;一個是不帶注釋是AT&T格式的。 Linux 0.11 中文注釋版 Linux 0.11 源碼&#xff0c;基于《Linux內核完全注釋》趙炯 1 asm.s 文件 我們先假設該文件處理的中斷是無特權過渡的情況…

【精華文】C語言結構體特殊情況分析:結構體指針 / 基本數據類型指針,指向其他結構體

參考鏈接&#xff1a;Structure pointer pointing to different structure instance 注&#xff1a;可以查看此篇的問題和唯一的回復&#xff0c;那是相對正確的&#xff0c;不要看comment&#xff0c;有很多錯誤。 我是拒絕分析這種問題的&#xff0c;因為似乎沒有人會這么亂用…

enum in c language

今天說說C語言中的枚舉。 參考&#xff1a;Enumeration (or enum) in C 1 定義 定義一個枚舉類型很容易&#xff1a; enum aa { a1, a2, a3 };這里 enum是關鍵字aa是枚舉變量&#xff0c;也就是我們自定義類型a1,a2,a3是枚舉成員 然后怎么使用呢&#xff1f; 首先&#…

信號量SIGCHLD的使用,如何讓父進程得知子進程執行結束,如何讓父進程區分多個子進程的結束

本教程基于 Ubuntu 20.10 gcc 10.2.0. 示例程序如果不能正常編譯和執行&#xff0c;說明您系統和工具版本與我的不匹配&#xff0c;請自行查閱資料。 0 概述 先給出該信號的描述&#xff1a; SignalValueDescriptionSIGCHLD17Child status has changed (POSIX). Signal sent …

使用gdb調試多進程程序、同時調試父進程和子進程

參考: [1] GDB debugging multi-process programs [2] Debugging programs with multiple processes 根據這兩篇參考鏈接&#xff0c;完全可以實現使用gdb同時調試父進程和子進程。 接下來說明一下可能遇到的坑 gdb8.1版本有bug&#xff0c;設置完set detach-fork-on off&…

Linux安裝Ncurses庫

參考&#xff1a;How To Install Ncurses Library In Linux 針對Ubuntu說明一下&#xff1a; wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.2.tar.gz&#xff0c;至于最新版本&#xff0c;自己看官網&#xff0c;修改一下版本號即可。tar xzf ncurses-6.2.tar.gzcd nc…

gdb 10.2的安裝

參考 [1] GDB-10.2 [2] README for GDB release 個人系統 Ubuntu20.10。 注意gdb10.2需要c11語法&#xff0c;需要安裝g 下載安裝包wget https://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.xz解壓縮tar -xvzf gdb-10.2.tar.xz進入解壓之后的目錄mkdir buildcd build配置&#xff0c;…

gdb tui的使用

[1] GDB Text User Interface [2] GDB Text User Interface 簡單來說&#xff0c;進入gdb之后&#xff0c;使用ctrl x 2就足夠了。其他細節請參考上述鏈接&#xff0c;選一個就可以。

C語言中信號函數(signal)的使用

先來簡單談談C語言中的信號&#xff08;signal&#xff09; 首先&#xff0c;signal是C語言庫中的函數&#xff0c;它實際上是軟中斷&#xff0c;也就是軟件發出的終端&#xff0c;本質來說&#xff0c;類似于int n。 對于接收到該軟中斷信號的進程&#xff0c;就會停下手頭的…

UNIX哲學

參考&#xff1a; 對比Linux與Windows 使用Linux想要做某些事情的時候&#xff0c;就拆開想&#xff0c;想想我需要哪些功能&#xff0c;需要哪些工具&#xff0c;依次怎么執行&#xff0c;然后用管道建立連接&#xff0c;讓數據依次流過不同的工具&#xff0c;從而得到最終結果…

fork創建多個子進程

references: [1] how to create two processes from a single Parent [2] fork() in C [3] linux中fork同時創建多個子進程的方法 fork的本質&#xff0c;就是復制&#xff0c;把當前進程復制一份&#xff0c;然后兩個進程并發地執行fork后面的語句&#xff0c;區別就是&#x…

wait系統調用

reference:Wait System Call in C 只強調幾點&#xff0c;剩下的直接看參考鏈接內容就好了&#xff0c;不是偷懶&#xff0c;而是里面內容寫的很好了&#xff0c;沒必要再寫一遍了&#xff0c;這種東西就是單純的系統調用而已&#xff0c;理解了功能&#xff0c;就完事了&#…

Linux進程間通信:共享內存與管道

references: [1] IPC through shared memory [2] Inter Process Communication (IPC) [3] https://www.geeksforgeeks.org/pipe-system-call/ [4] watch command in Linux with Examples 參考鏈接1和2是介紹了共享內存IPC的簡單原理和相關系統調用的使用參考鏈接3是介紹了管道通…

find command基本使用

find命令通常用于根據文件名查找文件&#xff0c;這是最基本用法。 find [path] -name/-iname [filename] path寫要查找的路徑&#xff0c;自動遞歸查找filename寫文件名&#xff0c;可以使用通配符*還有其他什么的表達式 具體細節請man find查閱文檔。