4.雙指針+遞歸

一、雙指針編程技巧

在這里插入圖片描述
方法參數傳遞數組
在這里插入圖片描述
將數組通過方法參數傳遞,方法操作的數組和main方法中的數組指向同一塊內存區域,意味著方法操作數組,同時會引起main方法中數組的改變以引用的方式作為方法參數進行傳遞的
元素交換
在這里插入圖片描述
定義臨時變量temp,每個都訪問了兩次,影響性能

1. 快慢指針

1.1 lc 283:移動零

給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。
請注意 ,必須在不復制數組的情況下原地對數組進行操作。
在這里插入圖片描述

1.2 樸素解法

在這里插入圖片描述
遍歷nums數組,將不為0的數據挪到tmp中,新建一個數組tmp將nums中的非零元素放入tmp中

 public int[] moveZeroes(int[] nums) {if(nums == null || nums.length ==0){return new int[]{};}int[] tmp = new int[nums.length];int j = 0;for (int i = 0; i < nums.length; i++) {if(nums[i]!=0){tmp[j] = nums[i];j++;}}return tmp;}?public static void main(String[] args) {int[] nums = new int[]{0,6,0,3,8,0};int[] res = new MoveZeros().moveZeroes(nums);System.out.println(Arrays.toString(res));}

1.3 移動零輸入輸出同一個數組

時間復雜度為O(n),空間復雜度為O(n)

 public void moveZeroes(int[] nums) {if(nums == null || nums.length ==0){return;}int[] tmp = new int[nums.length];int j = 0;for (int i = 0; i < nums.length; i++) {if(nums[i]!=0){tmp[j] = nums[i];j++;}}?//輸入輸出都在同一個數組for (int i = 0; i < nums.length; i++) {nums[i] = tmp[i];}}?public static void main(String[] args) {int[] nums = new int[]{0,6,0,3,8,0};new MoveZeros().moveZeroes(nums);System.out.println(Arrays.toString(nums));}

1.4 移動零雙指針解法

目的是在常量的空間復雜度下解決,不借助額外的數組
需要再使用一個指針j,用來指向非零元素存放的位置,指針i的話用來遍歷數組每個元素
在這里插入圖片描述
在這里插入圖片描述

1.5 移動零雙指針代碼實現

 //雙指針解法//時間復雜度為O(n)//空間復雜度為O(1)public void moveZeroes1(int[] nums) {if(nums == null || nums.length ==0){return;}int j = 0;for (int i = 0; i < nums.length; i++) {if(nums[i] !=0){//交換i和j指向的元素int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;j++;}}}

1.6 移動零雙指針之快慢指針

i指針走的快,j指針走的慢
用fast來代替i,slow代替j,提高代碼的可讀性

 public void moveZeroes1(int[] nums) {if(nums == null || nums.length ==0){return;}int slow = 0;for (int fast = 0; fast < nums.length; fast++) {if(nums[fast] !=0){//交換fast和slow指向的元素int tmp = nums[fast];nums[fast] = nums[slow];nums[slow] = tmp;slow++;}}}

1.7 移動零雙指針實現性能優化

減少兩個元素交換的次數
在這里插入圖片描述
當fast==slow的時候是不用交換的
交換的兩個元素都訪問了兩次
在這里插入圖片描述

直接將非零值賦值到slow指針指向位置,不進行交換,當fast走完
將slow指向元素都設置為0,直到結束

 //兩個元素不進行交換,直接賦值public void moveZeroes2(int[] nums) {if(nums == null || nums.length ==0){return;}int slow = 0;for (int fast = 0; fast < nums.length; fast++) {if(nums[fast] !=0){ //減少賦值的次數//交換fast和slow指向的元素if(slow!=fast){nums[slow] = nums[fast];}slow++;}}for (; slow < nums.length; slow++) {nums[slow] = 0;}}

2. 對撞指針

2.1 lc 344:反轉字符串

編寫一個函數,其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 s 的形式給出。
不要給另外的數組分配額外的空間,你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。
示例 1:
輸入:s = [“h”,“e”,“l”,“l”,“o”]
輸出:[“o”,“l”,“l”,“e”,“h”]
示例 2:
輸入:s = [“H”,“a”,“n”,“n”,“a”,“h”]
輸出:[“h”,“a”,“n”,“n”,“a”,“H”]

2.2 反轉字符串樸素解法

在這里插入圖片描述

 //樸素解法,定義一個額外數組用來存放反轉后的字符串//時間復雜度(n)//空間復雜度O(n)public void reverseString(char[] s) {char[] tmp = new char[s.length];int j = s.length-1;for (int i = 0; i < s.length; i++) {tmp[j] = s[i];j--;}for (int i = 0; i < s.length; i++) {s[i] = tmp[i];}}?public static void main(String[] args) {String s = "hello";char[] chars = s.toCharArray();new ReverseString().reverseString(chars);System.out.println(chars);}

2.3 反轉字符串雙指針解法

在這里插入圖片描述

 //雙指針解法public void reverseString1(char[] s) {int i = 0;int j = s.length-1;while (i<j){char tmp = s[i];s[i] = s[j];s[j] = tmp;i++;j--;}}

2.4 反轉字符串雙指針之對撞指針

一個指針是從左往右,一個是從右往左
左邊i指針設置為left,右邊設置為right

 //雙指針解法public void reverseString1(char[] s) {int left = 0;int right = s.length-1;while (left<right){char tmp = s[left];s[left] = s[right];s[right] = tmp;left++;right--;}}

3. 雙指針總結

使用一個指針可能會導致空間復雜度的升高
增加一個指針記錄更多的信息,可以降低空間復雜度,提升性能,降低時間復雜度

3.1 lc 27:移除元素

給你一個數組 nums 和一個值 val,你需要 原地 移除所有數值等于 val 的元素,并返回移除后數組的新長度。
不要使用額外的數組空間,你必須僅使用 O(1) 額外空間并 原地 修改輸入數組。
元素的順序可以改變。你不需要考慮數組中超出新長度后面的元素。
說明:
為什么返回數值是整數,但輸出的答案是數組呢?
請注意,輸入數組是以「引用」方式傳遞的,這意味著在函數里修改輸入數組對于調用者是可見的。
你可以想象內部操作如下:
// nums 是以“引用”方式傳遞的。也就是說,不對實參作任何拷貝
int len = removeElement(nums, val);// 在函數里修改輸入數組對于調用者是可見的。
// 根據你的函數返回的長度, 它會打印出數組中 該長度范圍內 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例 1:
輸入:nums = [3,2,2,3], val = 3
輸出:2, nums = [2,2]
解釋:函數應該返回新的長度 2, 并且 nums 中的前兩個元素均為 2。你不需要考慮數組中超出新長度后面的元素。例如,函數返回的新長度為 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也會被視作正確答案。
示例 2:
輸入:nums = [0,1,2,2,3,0,4,2], val = 2
輸出:5, nums = [0,1,4,0,3]
解釋:函數應該返回新的長度 5, 并且 nums 中的前五個元素為 0, 1, 3, 0, 4。注意這五個元素可為任意順序。你不需要考慮數組中超出新長度后面的元素。

3.2 移動元素雙指針解法

public int removeElement(int[] nums, int val) {//雙指針int j = 0;for (int i = 0; i < nums.length; i++) {if(nums[i] != val){nums[j] = nums[i];j++;}}return j;
}

3.3 lc 125:驗證回文串

給定一個字符串,驗證它是否是回文串,只考慮字母和數字字符,可以忽略字母的大小寫。
說明:本題中,我們將空字符串定義為有效的回文串。
示例 1:
輸入: “A man, a plan, a canal: Panama”
輸出: true
解釋:“amanaplanacanalpanama” 是回文串
示例 2:
輸入: “race a car”
輸出: false
解釋:“raceacar” 不是回文串

3.4 驗證回文串雙指針

public class lc125_Palindrome {public boolean isPalindrome(String s) {StringBuffer sb = new StringBuffer();int length = s.length();for (int i = 0; i < length; i++) {char ch = s.charAt(i);//isLetterOrDigit():確定指定的字符是字母還是數字。if (Character.isLetterOrDigit(ch)) {sb.append(Character.toLowerCase(ch));}}//回文判斷String s1 = sb.toString();char[] chars = s1.toCharArray();int left = 0;int right = chars.length-1;while (left < right){if(chars[left] != chars[right]){return false;}left++;right--;}return true;}
}

二、遞歸編程技巧

1. 方法調用系統棧

方法入棧,執行完某個方法后出棧
在這里插入圖片描述
方法入棧后一個方法對應一個棧幀,棧幀中包括局部變量表,操作數棧,動態連接,方法返回地址

2. 方法調用本身

在這里插入圖片描述
不斷調用方法本身,導致出現棧溢出的錯誤StackOverFlowException
需要給調用本身方法一個終止條件,避免一直調用下去
在這里插入圖片描述

3. 方法調用本身的參數變化

在這里插入圖片描述
調用方法前為1代碼塊
調用方法后為2代碼塊

4. 方法調用本身的意義

在這里插入圖片描述
使用另外一種思路解決:
在這里插入圖片描述
在這里插入圖片描述

遞歸程序的三個特點:

  1. 每個大問題可以拆分成若干個子問題,子問題解決了,大問題就解決了
  2. 每個子問題的解決方法和大問題的解決方法邏輯是一模一樣的
  3. 一定存在遞歸終止條件,一定存在最小子問題

遞推程序編寫:

  1. 寫出遞推公式
  2. 寫出遞歸終止條件

5. 斐波那契數

在這里插入圖片描述

//斐波那契數
public int fibonacci(int n){if(n==1)return 1;if(n==2)return 2;int fib1 = fibonacci(n-1);int fib2 = fibonacci(n-2);return fib1+fib2;
}

6. 走臺階

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

//1.遞推公式:f(n) = f(n-1) + f(n-2)
//2.遞推終止條件:f(1)=1,f(2)=2
public int walkStair(int n){if(n==1)return 1;if(n==2)return 2;int res = walkStair(n-1)+walkStair(n-2);return res;
}

三、學習分享

在這里插入圖片描述

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

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

相關文章

第十二節 SpringBoot Starter 系列結束語

感謝閱讀&#xff0c;到這里&#xff0c;本系列課程就結束了。 一、為什么選擇 SpringBoot Starter SpringBoot 近年來已經成為 Java 應用的必備框架&#xff1b; 而 SpringBoot starter 模式已經成為各大中間件集成到 SpringBoot 應用的首選方式&#xff0c;通過引入 xxx-st…

C++ | Leetcode C++題解之第101題對稱二叉樹

題目&#xff1a; 題解&#xff1a; class Solution { public:bool check(TreeNode *u, TreeNode *v) {queue <TreeNode*> q;q.push(u); q.push(v);while (!q.empty()) {u q.front(); q.pop();v q.front(); q.pop();if (!u && !v) continue;if ((!u || !v) ||…

爬蟲基礎1

一、爬蟲的基本概念 1.什么是爬蟲&#xff1f; 請求網站并提取數據的自動化程序 2.爬蟲的分類 2.1 通用爬蟲&#xff08;大而全&#xff09; 功能強大&#xff0c;采集面廣&#xff0c;通常用于搜索引擎&#xff1a;百度&#xff0c;360&#xff0c;谷歌 2.2 聚焦爬蟲&#x…

Android App啟動流程和源碼詳解

前言 之前看了些App啟動流程的文章&#xff0c;但是看得很淺顯&#xff0c;隔了沒多久就忘了&#xff0c;自己抓耳撓腮的終于看完了&#xff0c;看得頭疼哦。因為很多是個人理解&#xff0c;大哥們主打一個7分信&#xff0c;2分思考&#xff0c;1分懷疑哈。 主要看的源碼是An…

pytorch-20_1 LSTM在股價數據集上的預測實戰

LSTM在股價數據集上的預測實戰 使用完整的JPX賽題數據&#xff0c;并向大家提供完整的lstm流程。 導包 import numpy as np #數據處理 import pandas as pd #數據處理 import matplotlib as mlp import matplotlib.pyplot as plt #繪圖 from sklearn.preprocessing import M…

人類交互4 感覺輸入和運動輸出

人類感覺系統概述 人類感覺系統是由多個感覺器官和神經系統組成&#xff0c;負責感知外部世界的各種刺激和信息。人類感覺系統包括以下幾個主要部分&#xff1a; 視覺系統&#xff1a;視覺系統由眼睛、視神經和大腦視覺皮層組成&#xff0c;負責感知光線、顏色和形狀&#xff…

datasheet芯片數據手冊—新手入門學習(二)【8-18】

參考芯片手冊已經上傳&#xff0c;可自行下載 因為芯片參考手冊內容比較多&#xff0c;故再一次介紹本文內容主要講解章節。 目錄 8、內容介紹 命令真值表 9、Command Definitions 10、READ Operations &#xff08;1&#xff09;頁面讀取操作 &#xff08;2&#xff…

YTM32的flash應用答疑-詳解寫保護功能

YTM32的flash應用答疑-詳解寫保護功能 文章目錄 YTM32的flash應用答疑-詳解寫保護功能IntroductionPrincipleOperation & DemonstrationDemo #1 驗證基本的寫保護功能Demo #2 編程CUS_NVR設定EFM_ADDR_PROT初值Demo #3 啟用寫保護后試試塊擦除操作 Conclusion Introduction…

報名倒計時兩周|2024 OpenTiny 開源之夏項目直播解讀回顧

5月16日&#xff0c;OpenTiny 開源社區成功舉辦了以《OpenTiny 開源之夏項目解讀直播》為主題的直播活動。此次直播中&#xff0c;華為云的高級前端工程師曾令卡、華為云的高級前端工程師伍其和與10位開源之夏技術專家攜手組成項目導師團&#xff0c;面向廣大開發者一同深入探討…

Java類和對象(五)—— 抽象類、接口、Object類和內部類

抽象類 在繼承體系下&#xff0c;父類有些方法可能是要被重寫的&#xff0c;如果我們事先就知道某些方法需要重寫的話&#xff0c;我們可以不用在父類里面具體實現這個方法&#xff0c;這時候我們會用到抽象方法&#xff0c;這時候我們會用到關鍵字abstract關鍵字來修飾 publ…

BatBot智慧能源管理平臺,更加有效地管理能源

隨著能源消耗的不斷增加&#xff0c;能源管理已成為全球面臨的重要問題。BatBot智慧能源管理作為一種的能源管理技術&#xff0c;促進企業在用能效率及管理有著巨大的提升。 BatBot智慧能源管理是一種基于人工智能技術的能源管理系統&#xff0c;通過智能分析和優化能源使用&…

【JAVA |再談接口、Object、內部類】Object類中子類重寫,Cloneable 接口、比較器、內部類

??謝謝大家捧場&#xff0c;祝屏幕前的小伙伴們每天都有好運相伴左右&#xff0c;一定要天天開心哦&#xff01;?? &#x1f388;&#x1f388;作者主頁&#xff1a; &#x1f388;丠丠64-CSDN博客&#x1f388; ?? 帥哥美女們&#xff0c;我們共同加油&#xff01;一起…

Internet動態路由選擇—RIP與OSPF

剛做完網絡層動態路由選擇的實驗&#xff0c;寫下此篇記錄實驗過程&#xff0c;鞏固學習成果。 參考書目&#xff1a;《計算機網絡》北京理工大學出版社-劉陽老師編 路由選擇可分為兩種策略&#xff1a; - 靜態路由選擇策略 - 動態路由選擇策略 靜態路由即管理員手動配置路由…

Java 商品入庫系統 案例

測試類 package 練習.商品入庫系統;import java.util.ArrayList; import java.util.Scanner; public class Test {public static final int Enrool 1;public static final int Search 2;public static final int Delect 3;public static final int Exit 4;public static…

在docker上部署postgresSQL主從

文章目錄 一、主從規劃二、創建PostgresSQL的Docker鏡像三、主庫部署1、建立pgsql主庫的data地址2、啟動docker鏡像3、docker內操作4、修改配置文件 四、部署從數據庫1、建立psql備庫的data地址2、啟動docker鏡像3、備庫從主庫同步4、檢查是否同步 五、測試主從數據庫 一、主從…

#2495. 滑動窗口 /【模板】單調隊列

題目描述 有一個長為 ( n ) 的序列 ( a )&#xff0c;以及一個大小為 ( k ) 的窗口。現在這個窗口從左邊開始向右滑動&#xff0c;每次滑動一個單位&#xff0c;求出每次滑動后窗口中的最大值和最小值。例如&#xff1a; 數組是 ([1, 3, -1, -3, 5, 3, 6, 7])&#xff0c; ( …

【深度強化學習】關于同一設備上cuda和gpu計算結果不一致問題

文章目錄 問題描述關于seed: 跟原文一致補充:萬能seed 問題結論cpu和gpu差異來源分析浮點數精度的差異補充報錯&#xff1a;Expected all tensors to be on the same device&#xff01;常見運算上的差異累加運算的差異exp運算的差異matmul運算的差異 forward上的差異&#xff…

【LeetCode 隨筆】面試經典 150 題【中等+困難】持續更新中。。。

文章目錄 189. 輪轉數組122. 買賣股票的最佳時機 II55. 跳躍游戲45. 跳躍游戲 II274. H 指數 &#x1f308;你好呀&#xff01;我是 山頂風景獨好 &#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01; &#x1f49d;希望您在這里可以感受到一份輕松…

機器學習云環境搭建

在 https://support.huaweicloud.com/browsertg-obs/obs_03_1003.html 下載對應版本的 OBS Broswer 軟件&#xff0c;如圖&#xff0c;紅框內的為安裝文件&#xff0c;藍色框內的為對應安裝文件的校驗文件&#xff08;無需下載&#xff09; 以 64 位機為例&#xff0c;下載完…