日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

LeetCode详解C++版

發布時間:2023/12/10 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode详解C++版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

打算把LeetCode上面的題都實現一遍,每日兩題

LeetCode目錄

      • 1. 兩數之和
      • 2. 兩數相加
      • 11. 盛最多水的容器
      • 15.三數之和
      • 33.搜索旋轉排序數組
      • 34. 在排序數組中查找元素的第一個和最后一個位置
      • 35.搜索插入位置
      • 53.最大子數組和
      • 64. 最小路徑和
      • 70.爬樓梯
      • 74.搜索二維矩陣
      • 82. 刪除排序鏈表中的重復元素 II
      • 88. 合并兩個有序數組
      • 153. 尋找旋轉排序數組中的最小值
      • 162. 尋找峰值
      • 167. 兩數之和 II - 輸入有序數組
      • 189.輪轉數組
      • 217.存在重復元素
      • 278.第一個錯誤的版本
      • 283. 移動零
      • 344. 反轉字符串
      • 557. 反轉字符串中的單詞 III
      • 704. 二分查找
      • 844. 比較含退格的字符串
      • 977. 有序數組的平方
      • 986. 區間列表的交集
      • 劍指 Offer 05. 替換空格
      • 劍指 Offer 06. 從尾到頭打印鏈表
      • 劍指 Offer 09.用兩個棧實現隊列
      • 劍指 Offer 24. 反轉鏈表
      • 劍指 Offer 30.包含min函數的棧

1. 兩數之和

給定一個整數數組 nums 和一個整數目標值 target,請你在該數組中找出 和為目標值 target 的那 兩個 整數,并返回它們的數組下標。
你可以假設每種輸入只會對應一個答案。但是,數組中同一個元素在答案里不能重復出現。
你可以按任意順序返回答案。

示例 1: 輸入:nums = [2,7,11,15], target = 9 輸出:[0,1] 解釋:因為 nums[0] + nums[1] == 9 ,返回 [0, 1] 。 示例 2: 輸入:nums = [3,2,4], target = 6 輸出:[1,2] 示例 3: 輸入:nums = [3,3], target = 6 輸出:[0,1]

思路
巧用map結構
代碼

class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hamap;int x = -1;for (int i = 0; i < nums.size(); i++){x = target - nums[i];if (hamap.find(x) != hamap.end()){return{ hamap.find(x)->second, i };}hamap[nums[i]] = i;}return {};} };

2. 兩數相加

給你兩個 非空 的鏈表,表示兩個非負的整數。它們每位數字都是按照 逆序 的方式存儲的,并且每個節點只能存儲 一位 數字。
請你將兩個數相加,并以相同形式返回一個表示和的鏈表。
你可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。

思路

代碼

class Solution { public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* sumnode = new ListNode(-1);ListNode* head = sumnode;int sum=0;bool carry=false;while(l1!=NULL || l2!=NULL){sum = 0;if(l1!=NULL){sum += l1->val;l1 = l1->next;}if(l2!=NULL){sum += l2->val;l2 = l2->next;}if(carry){sum++;}head->next = new ListNode(sum%10);head = head->next;if(sum >= 10){carry = true;}else{carry = false;}}if(sum >= 10){head->next = new ListNode(1);}return sumnode->next;} };

改進版

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/ class Solution { public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode* re = new ListNode(0);ListNode* r = re;int carry=0;while(l1!=NULL || l2!=NULL){int x = 0;int y = 0;if(l1!=NULL){x = l1->val; }else{x = 0;}if(l2!=NULL){y = l2->val; }else{y = 0;}int s = carry + x + y;carry = s/10;r->next = new ListNode(s%10);r = r->next;if(l1!=NULL){l1 = l1->next;}if(l2!=NULL){l2 = l2->next;} }if(carry > 0){r->next = new ListNode(1);}return re->next;} };

11. 盛最多水的容器

給定一個長度為 n 的整數數組 height 。有 n 條垂線,第 i 條線的兩個端點是 (i, 0) 和 (i, height[i]) 。
找出其中的兩條線,使得它們與 x 軸共同構成的容器可以容納最多的水。
返回容器可以儲存的最大水量。
說明:你不能傾斜容器。

示例 1: 輸入:[1,8,6,2,5,4,8,3,7] 輸出:49 解釋:圖中垂直線代表輸入數組 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍色部分)的最大值為 49。 示例 2: 輸入:height = [1,1] 輸出:1

思路
使用雙指針 注意!我們每次只要移動高度小的一邊,因為移動小的那一邊可能會增大,但是移動大的一邊一定會減小
代碼

class Solution { public:int maxArea(vector<int>& height) {int i = 0,j = height.size()-1,res = 0;while(i < j){if(height[i]<height[j]){res = max(res,height[i]*(j-i));i++;}else{res = max(res,height[j]*(j-i));j--;}}return res;} };

15.三數之和

給你一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?請你找出所有和為 0 且不重復的三元組。
注意:答案中不可以包含重復的三元組。

示例 1: 輸入:nums = [-1,0,1,2,-1,-4] 輸出:[[-1,-1,2],[-1,0,1]] 示例 2: 輸入:nums = [] 輸出:[] 示例 3: 輸入:nums = [0] 輸出:[]

思路
可以使用雙指針,先排序(時間復雜度nlogn),然后令L = i+1 ,R = n - 1,我們遍歷i,如果值大了我們就R–,小了就L++
代碼

class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> ans;if(nums.size()<3) return ans;sort(nums.begin(), nums.end());if(nums[0]>0) return ans;for(int i=0;i<nums.size();i++){if(nums[i]>0) return ans;if(i>0 && nums[i] == nums[i-1]) continue; int left = i+1, right = nums.size()-1;while(left< right){if(nums[i] + nums[left] + nums[right] == 0){ans.push_back({nums[i], nums[left], nums[right]});while(left<right && nums[left] == nums[left+1])left++;while(left<right && nums[right] == nums[right-1])right--;left++;right--;}else if(nums[i] + nums[left] + nums[right] > 0) right--;else left++;} }return ans;} };

33.搜索旋轉排序數組

整數數組 nums 按升序排列,數組中的值 互不相同 。

在傳遞給函數之前,nums 在預先未知的某個下標 k(0 <= k < nums.length)上進行了 旋轉,使數組變為 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下標 從 0 開始 計數)。例如, [0,1,2,4,5,6,7] 在下標 3 處經旋轉后可能變為 [4,5,6,7,0,1,2] 。
給你 旋轉后 的數組 nums 和一個整數 target ,如果 nums 中存在這個目標值 target ,則返回它的下標,否則返回 -1 。

示例 1: 輸入:nums = [4,5,6,7,0,1,2], target = 0 輸出:4 示例 2: 輸入:nums = [4,5,6,7,0,1,2], target = 3 輸出:-1 示例 3: 輸入:nums = [1], target = 0 輸出:-1

思路
二分查找題,先用二分查找找到k,然后找到目標值
代碼

class Solution { public:int search(vector<int>& nums, int target) {if(nums.empty()) return -1;int n = nums.size(),r = n-1,l = 0;// find kwhile(l<r){int m = l + (r -l)/2;if(nums[m] < nums[r]) r = m;else l = m+1;}int k = l;l = 0;r = k-1;while(l<r){int m = l + (r -l)/2;if(nums[m] >= target) r = m;else l = m+1;}if(nums[l] == target) return l;l = k;r = n-1;while(l<r){int m = l + (r -l)/2;if(nums[m] >= target) r = m;else l = m+1;}if(nums[l] == target) return l;return -1;} };

34. 在排序數組中查找元素的第一個和最后一個位置

給定一個按照升序排列的整數數組 nums,和一個目標值 target。找出給定目標值在數組中的開始位置和結束位置。
如果數組中不存在目標值 target,返回 [-1, -1]。
進階:
你可以設計并實現時間復雜度為 O(log n) 的算法解決此問題嗎?

示例 1: 輸入:nums = [5,7,7,8,8,10], target = 8 輸出:[3,4] 示例 2: 輸入:nums = [5,7,7,8,8,10], target = 6 輸出:[-1,-1] 示例 3: 輸入:nums = [], target = 0 輸出:[-1,-1]

思路
兩分查找,先找開始的位置,在找結束的位置。
代碼

class Solution { public:vector<int> searchRange(vector<int>& nums, int target) {vector<int> res(2,-1);if(nums.empty()) return res;int n = nums.size(),l = 0, r = n-1;while(l < r){int m = l + (r - l)/2;if(nums[m] >= target){r = m;}else{l = m + 1;}}if(nums[l] != target) return res;res[0] = l;r = n;while(l < r){int m = l + (r - l)/2;if(nums[m] <= target){l = m + 1;}else{r = m;}}res[1] = l - 1;return res;} };

35.搜索插入位置

給定一個排序數組和一個目標值,在數組中找到目標值,并返回其索引。如果目標值不存在于數組中,返回它將會被按順序插入的位置。
請必須使用時間復雜度為 O(log n) 的算法。

示例 1: 輸入: nums = [1,3,5,6], target = 5 輸出: 2示例 2: 輸入: nums = [1,3,5,6], target = 2 輸出: 1示例 3: 輸入: nums = [1,3,5,6], target = 7 輸出: 4示例 4: 輸入: nums = [1,3,5,6], target = 0 輸出: 0示例 5: 輸入: nums = [1], target = 0 輸出: 0

思路

代碼

class Solution { public:int searchInsert(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;while(left <= right){int mid = left + (right - left)/2;if(nums[mid] < target){left = mid + 1;}else {right = mid - 1;}}return left;} };

53.最大子數組和

給你一個整數數組 nums ,請你找出一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
子數組 是數組中的一個連續部分。

示例 1: 輸入:nums = [-2,1,-3,4,-1,2,1,-5,4] 輸出:6 解釋:連續子數組 [4,-1,2,1] 的和最大,為 6 。 示例 2: 輸入:nums = [1] 輸出:1 示例 3: 輸入:nums = [5,4,-1,7,8] 輸出:23

思路
可以使用動態規劃的方法,如下代碼,f_n表示前n個之和最大值
代碼

class Solution { public:int maxSubArray(vector<int>& nums) {if(nums.size() == 0) return NULL;int res = INT_MIN;int f_n = -1;for(int i = 0; i < nums.size(); ++i){f_n = max(nums[i], f_n + nums[i]);res = max(f_n, res);}return res;} };

64. 最小路徑和

給定一個包含非負整數的 m x n 網格 grid ,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。
說明:每次只能向下或者向右移動一步。

思路

代碼

class Solution { public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size();int n = grid[0].size();if(m <= 0 || n <= 0){return 0;}int dp[m][n];dp[0][0] = grid[0][0];for(int i = 1;i < m;i++){dp[i][0] = grid[i][0] + dp[i-1][0];}for(int i = 1;i < n;i++){dp[0][i] = grid[0][i] + dp[0][i-1]; }for(int i = 1;i < m;i++){for(int j = 1;j < n;j++){dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + grid[i][j];}}return dp[m-1][n-1];} };

70.爬樓梯

假設你正在爬樓梯。需要 n 階你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
注意:給定 n 是一個正整數。

示例 1: 輸入: 2 輸出: 2 解釋: 有兩種方法可以爬到樓頂。 1. 1+ 12. 2 階示例 2: 輸入: 3 輸出: 3 解釋: 有三種方法可以爬到樓頂。 1. 1+ 1+ 12. 1+ 23. 2+ 1

思路

代碼

class Solution { public:int climbStairs(int n) {int a[n+1];if(n <= 2){return n;}a[0] = 0;a[1] = 1;a[2] = 2;for(int i = 3;i <= n;i++){a[i] = a[i-1] + a[i-2];}return a[n];} };

74.搜索二維矩陣

編寫一個高效的算法來判斷 m x n 矩陣中,是否存在一個目標值。該矩陣具有如下特性:
每行中的整數從左到右按升序排列。
每行的第一個整數大于前一行的最后一個整數。

思路
將二維排序成一維來做,繼續用二分查找
代碼

class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int n = matrix.size(), m = matrix[0].size();int l = 0,r = n*m-1;while(l<r){int mid = l + (r - l)/2;int mid1 = mid/m,mid2 = mid%m;if(matrix[mid1][mid2] >= target) r = mid;else l = mid + 1;}int ma1 = l/m,ma2 = l%m;if(matrix[ma1][ma2] == target) return true;return false;} };

82. 刪除排序鏈表中的重復元素 II

給定一個已排序的鏈表的頭 head , 刪除原始鏈表中所有重復數字的節點,只留下不同的數字 。返回 已排序的鏈表 。

思路
很容易的題,主要是第一個值的話怎么刪,我們可以新建一個next 為列表的頭head
代碼

class Solution { public:ListNode* deleteDuplicates(ListNode* head) {if(head == NULL || head->next == NULL) return head;ListNode* tem = new ListNode(0, head);ListNode* cur = tem;while (cur->next && cur->next->next) {if (cur->next->val == cur->next->next->val) {int x = cur->next->val;while (cur->next && cur->next->val == x) {cur->next = cur->next->next;}}else {cur = cur->next;}}return tem->next;} };

88. 合并兩個有序數組

給你兩個按 非遞減順序 排列的整數數組 nums1 和 nums2,另有兩個整數 m 和 n ,分別表示 nums1 和 nums2 中的元素數目。
請你 合并 nums2 到 nums1 中,使合并后的數組同樣按 非遞減順序 排列。
注意:最終,合并后數組不應由函數返回,而是存儲在數組 nums1 中。為了應對這種情況,nums1 的初始長度為 m + n,其中前 m 個元素表示應合并的元素,后 n 個元素為 0 ,應忽略。nums2 的長度為 n 。

示例 1: 輸入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 輸出:[1,2,2,3,5,6] 解釋:需要合并 [1,2,3][2,5,6] 。 合并結果是 [1,2,2,3,5,6] ,其中斜體加粗標注的為 nums1 中的元素。 示例 2: 輸入:nums1 = [1], m = 1, nums2 = [], n = 0 輸出:[1] 解釋:需要合并 [1][] 。 合并結果是 [1] 。 示例 3: 輸入:nums1 = [0], m = 0, nums2 = [1], n = 1 輸出:[1] 解釋:需要合并的數組是 [][1] 。 合并結果是 [1] 。 注意,因為 m = 0 ,所以 nums1 中沒有元素。nums1 中僅存的 0 僅僅是為了確保合并結果可以順利存放到 nums1 中。

思路
我們巧用nums1的結構,把從大到小排序放進去
代碼

class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {int last = m+n-1;while(n){if(m==0||nums1[m-1]<=nums2[n-1]){nums1[last--]=nums2[--n];}else{nums1[last--]=nums1[--m];}}} };

153. 尋找旋轉排序數組中的最小值

已知一個長度為 n 的數組,預先按照升序排列,經由 1 到 n 次 旋轉 后,得到輸入數組。例如,原數組 nums = [0,1,2,4,5,6,7] 在變化后可能得到:
若旋轉 4 次,則可以得到 [4,5,6,7,0,1,2]
若旋轉 7 次,則可以得到 [0,1,2,4,5,6,7]
注意,數組 [a[0], a[1], a[2], …, a[n-1]] 旋轉一次 的結果為數組 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
給你一個元素值 互不相同 的數組 nums ,它原來是一個升序排列的數組,并按上述情形進行了多次旋轉。請你找出并返回數組中的 最小元素 。
你必須設計一個時間復雜度為 O(log n) 的算法解決此問題。

示例 1: 輸入:nums = [3,4,5,1,2] 輸出:1 解釋:原數組為 [1,2,3,4,5] ,旋轉 3 次得到輸入數組。 示例 2: 輸入:nums = [4,5,6,7,0,1,2] 輸出:0 解釋:原數組為 [0,1,2,4,5,6,7] ,旋轉 4 次得到輸入數組。 示例 3: 輸入:nums = [11,13,15,17] 輸出:11 解釋:原數組為 [11,13,15,17] ,旋轉 4 次得到輸入數組。

思路
查找旋轉次數就好了
代碼

class Solution { public:int findMin(vector<int>& nums) {if(nums.empty()) return -1;int n = nums.size(),r = n-1,l = 0;// find k 旋轉次數while(l<r){int m = l + (r -l)/2;if(nums[m] < nums[r]) r = m;else l = m+1;}return nums[l];} };

162. 尋找峰值

峰值元素是指其值嚴格大于左右相鄰值的元素。
給你一個整數數組 nums,找到峰值元素并返回其索引。數組可能包含多個峰值,在這種情況下,返回 任何一個峰值 所在位置即可。
你可以假設 nums[-1] = nums[n] = -∞ 。
你必須實現時間復雜度為 O(log n) 的算法來解決此問題。

示例 1: 輸入:nums = [1,2,3,1] 輸出:2 解釋:3 是峰值元素,你的函數應該返回其索引 2。 示例 2: 輸入:nums = [1,2,1,3,5,6,4] 輸出:15 解釋:你的函數可以返回索引 1,其峰值元素為 2;或者返回索引 5, 其峰值元素為 6

思路
二分法,只需要判斷nums[m] > nums[m+1],因為大的值一定有解
代碼

class Solution { public:int findPeakElement(vector<int>& nums) {int n = nums.size(),r = n-1,l = 0;while(l<r){int m = l + (r - l)/2;if(nums[m] > nums[m+1]) r = m;else l = m+1;}return l;} };

167. 兩數之和 II - 輸入有序數組

給定一個已按照 非遞減順序排列 的整數數組 numbers ,請你從數組中找出兩個數滿足相加之和等于目標數 target 。
函數應該以長度為 2 的整數數組的形式返回這兩個數的下標值。numbers 的下標 從 1 開始計數 ,所以答案數組應當滿足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假設每個輸入 只對應唯一的答案 ,而且你 不可以 重復使用相同的元素。

示例 1: 輸入:numbers = [2,7,11,15], target = 9 輸出:[1,2] 解釋:27 之和等于目標數 9 。因此 index1 = 1, index2 = 2 。示例 2: 輸入:numbers = [2,3,4], target = 6 輸出:[1,3]示例 3: 輸入:numbers = [-1,0], target = -1 輸出:[1,2]

思路

代碼

class Solution { public:vector<int> twoSum(vector<int>& numbers, int target) {int l = 0;int r = numbers.size() - 1;while(l<r){if(numbers[l]+numbers[r]>target){r--;}else if(numbers[l]+numbers[r]<target){l++;}else{return {l+1,r+1};}}return {l+1,r+1};} };

189.輪轉數組

給你一個數組,將數組中的元素向右輪轉 k 個位置,其中 k 是非負數。

示例 1: 輸入: nums = [1,2,3,4,5,6,7], k = 3 輸出: [5,6,7,1,2,3,4] 解釋: 向右輪轉 1: [7,1,2,3,4,5,6] 向右輪轉 2: [6,7,1,2,3,4,5] 向右輪轉 3: [5,6,7,1,2,3,4]示例 2: 輸入:nums = [-1,-100,3,99], k = 2 輸出:[3,99,-1,-100] 解釋: 向右輪轉 1: [99,-1,-100,3] 向右輪轉 2: [3,99,-1,-100]

思路

代碼

class Solution { public:void rotate(vector<int>& nums, int k) {int n = nums.size();k = k % n;int count = gcd(k, n);for (int start = 0; start < count; ++start) {int current = start;int prev = nums[start];do {int next = (current + k) % n;swap(nums[next], prev);current = next;} while (start != current);}} };

217.存在重復元素

給你一個整數數組 nums 。如果任一值在數組中出現 至少兩次 ,返回 true ;如果數組中每個元素互不相同,返回 false 。

示例 1: 輸入:nums = [1,2,3,1] 輸出:true 示例 2: 輸入:nums = [1,2,3,4] 輸出:false 示例 3: 輸入:nums = [1,1,1,3,3,4,3,2,4,2] 輸出:true

思路
利用集合的唯一性來做。(暴力窮舉算法復雜度太大了O(n2)O(n^2)O(n2)
代碼

class Solution { public:bool containsDuplicate(vector<int>& nums) {unordered_set<int> s;for (int x: nums) {if (s.find(x) != s.end()) {return true;}s.insert(x);}return false;} };

278.第一個錯誤的版本

你是產品經理,目前正在帶領一個團隊開發新的產品。不幸的是,你的產品的最新版本沒有通過質量檢測。由于每個版本都是基于之前的版本開發的,所以錯誤的版本之后的所有版本都是錯的。
假設你有 n 個版本 [1, 2, …, n],你想找出導致之后所有版本出錯的第一個錯誤的版本。
你可以通過調用 bool isBadVersion(version) 接口來判斷版本號 version 是否在單元測試中出錯。實現一個函數來查找第一個錯誤的版本。你應該盡量減少對調用 API 的次數。

示例 1: 輸入:n = 5, bad = 4 輸出:4 解釋: 調用 isBadVersion(3) -> false 調用 isBadVersion(5) -> true 調用 isBadVersion(4) -> true 所以,4 是第一個錯誤的版本。示例 2: 輸入:n = 1, bad = 1 輸出:1

思路

代碼

class Solution { public:int firstBadVersion(int n) {int l = 1, r = n, m = 0; while (l<r){m = l + ((r - l) >> 1);if(isBadVersion(m))r = m;elsel = m + 1;} return l;} };

283. 移動零

給定一個數組 nums,編寫一個函數將所有 0 移動到數組的末尾,同時保持非零元素的相對順序。

示例: 輸入: [0,1,0,3,12] 輸出: [1,3,12,0,0]

思路

代碼

class Solution { public:void moveZeroes(vector<int>& nums) {int m = nums.size(),j = 0;for(int i = 0;i < m;i++){if(nums[i]!=0){nums[j++] = nums[i];}}for(int i = j;j < m;j++){nums[j] = 0;}} };

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"]

思路

代碼

class Solution { public:void reverseString(vector<char>& s) { int r = s.size();int l = r;for(int i = 0; i<r/2;i++){l--;char tmp = s[i];s[i] = s[l];s[l] = tmp;}} };

一行實現

class Solution { public:void reverseString(vector<char>& s) { s.reverse()} };

557. 反轉字符串中的單詞 III

給定一個字符串,你需要反轉字符串中每個單詞的字符順序,同時仍保留空格和單詞的初始順序。

示例: 輸入:"Let's take LeetCode contest" 輸出:"s'teL ekat edoCteeL tsetnoc"

思路

代碼

class Solution { public:string reverseWords(string s) {int n=s.size();int begin=0,end;for(int i=0;i<n+1;i++){if(s[i]==' '||s[i]=='\0'){for(end=i-1;begin<end;begin++,end--){swap(s[begin],s[end]);}begin=i+1;}}return s;} };

704. 二分查找

給定一個 n 個元素有序的(升序)整型數組 nums 和一個目標值 target ,寫一個函數搜索 nums 中的 target,如果目標值存在返回下標,否則返回 -1。

示例 1: 輸入: nums = [-1,0,3,5,9,12], target = 9 輸出: 4 解釋: 9 出現在 nums 中并且下標為 4示例 2: 輸入: nums = [-1,0,3,5,9,12], target = 2 輸出: -1 解釋: 2 不存在 nums 中因此返回 -1

思路

代碼

class Solution { public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;while(left <= right){int mid = left + (right - left)/2;if(nums[mid] < target){left = mid + 1;}else if(nums[mid] > target){right = mid - 1;}else{return mid;} }return -1;} };

844. 比較含退格的字符串

給定 s 和 t 兩個字符串,當它們分別被輸入到空白的文本編輯器后,如果兩者相等,返回 true 。# 代表退格字符。
注意:如果對空文本輸入退格字符,文本繼續為空。

示例 1: 輸入:s = "ab#c", t = "ad#c" 輸出:true 解釋:s 和 t 都會變成 "ac"。 示例 2: 輸入:s = "ab##", t = "c#d#" 輸出:true 解釋:s 和 t 都會變成 ""。 示例 3: 輸入:s = "a#c", t = "b" 輸出:false 解釋:s 會變成 "c",但 t 仍然是 "b"

思路
如果暴力的話肯定不行的,要占用新的內存,且要比較。我們可以使用雙指針,從后往前讀,比較每一個字符。有不符號返回flase
代碼

class Solution { public:bool backspaceCompare(string s, string t) {int i = s.size() - 1, j = t.size() - 1;int skipS = 0, skipT = 0;while (i >= 0 || j >= 0) {while (i >= 0) {if (s[i] == '#') {skipS++, i--;} else if (skipS > 0) {skipS--, i--;} else {break;}}while (j >= 0) {if (t[j] == '#') {skipT++, j--;} else if (skipT > 0) {skipT--, j--;} else {break;}}if (i >= 0 && j >= 0) {if (s[i] != t[j]) {return false;}} else {if (i >= 0 || j >= 0) {return false;}}i--, j--;}return true;} };

977. 有序數組的平方

給你一個按 非遞減順序 排序的整數數組 nums,返回每個數字的平方 組成的新數組,要求也按非遞減順序排序。

示例 1:輸入:nums = [-4,-1,0,3,10] 輸出:[0,1,9,16,100] 解釋:平方后,數組變為 [16,1,0,9,100] 排序后,數組變為 [0,1,9,16,100]示例 2: 輸入:nums = [-7,-3,2,3,11] 輸出:[4,9,9,49,121]提示: 1 <= nums.length <= 104 -104 <= nums[i] <= 104 nums 已按 非遞減順序 排序進階: 請你設計時間復雜度為 O(n) 的算法解決本問題

思路

代碼

class Solution { public:vector<int> sortedSquares(vector<int>& nums) {for(int i=0;i<nums.size();i++){nums[i] = nums[i]*nums[i];}sort(nums.begin(),nums.end());return nums;} };

986. 區間列表的交集

給定兩個由一些 閉區間 組成的列表,firstList 和 secondList ,其中 firstList[i] = [starti, endi] 而 secondList[j] = [startj, endj] 。每個區間列表都是成對 不相交 的,并且 已經排序 。
返回這 兩個區間列表的交集 。
形式上,閉區間 [a, b](其中 a <= b)表示實數 x 的集合,而 a <= x <= b 。
兩個閉區間的 交集 是一組實數,要么為空集,要么為閉區間。例如,[1, 3] 和 [2, 4] 的交集為 [2, 3] 。

示例 1: 輸入:firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]] 輸出:[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] 示例 2: 輸入:firstList = [[1,3],[5,9]], secondList = [] 輸出:[] 示例 3: 輸入:firstList = [], secondList = [[4,8],[10,12]] 輸出:[] 示例 4: 輸入:firstList = [[1,7]], secondList = [[3,10]] 輸出:[[3,7]]

思路
使用雙指針,一個指向其中一個數組,對每一個內部數組進行比較。
代碼

class Solution { public:vector<vector<int>> intervalIntersection(vector<vector<int>>& firstList, vector<vector<int>>& secondList) {vector<vector<int>> res;if(firstList.empty()||secondList.empty()) return res;int i = 0,j = 0;while(i < firstList.size() && j < secondList.size()){int start = max(firstList[i][0],secondList[j][0]);int end = min(firstList[i][1],secondList[j][1]);if(start <= end) res.push_back({start,end});if(firstList[i][1] < secondList[j][1]) i++;else j++;}return res;} };

劍指 Offer 05. 替換空格

請實現一個函數,把字符串 s 中的每個空格替換成"%20"。

示例 1: 輸入:s = "We are happy." 輸出:"We%20are%20happy."

思路

代碼

class Solution { public:string replaceSpace(string s) {int count = 0; // 統計空格的個數int sOldSize = s.size();for (int i = 0; i < s.size(); i++) {if (s[i] == ' ') {count++;}}// 擴充字符串s的大小,也就是每個空格替換成"%20"之后的大小s.resize(s.size() + count * 2);int sNewSize = s.size();// 從后先前將空格替換為"%20"for (int i = sNewSize - 1, j = sOldSize - 1; j < i; i--, j--) {if (s[j] != ' ') {s[i] = s[j];} else {s[i] = '0';s[i - 1] = '2';s[i - 2] = '%';i -= 2;}}return s;} };

劍指 Offer 06. 從尾到頭打印鏈表

輸入一個鏈表的頭節點,從尾到頭反過來返回每個節點的值(用數組返回)。

示例 1: 輸入:head = [1,3,2] 輸出:[2,3,1]

思路

代碼

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:vector<int> reversePrint(ListNode* head) {vector<int> res;while(head){res.push_back(head->val);head=head->next;}reverse(res.begin(),res.end());return res;} };

劍指 Offer 09.用兩個棧實現隊列

用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTail 和 deleteHead ,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能。(若隊列中沒有元素,deleteHead 操作返回 -1 )
思路

代碼

class CQueue { public:stack<int>s1;stack<int>s2;CQueue() {}void appendTail(int value) {s1.push(value);}int deleteHead() {if(s1.empty() && s2.empty()){return -1;}if(!s1.empty() && s2.empty()){while(!s1.empty()){s2.push(s1.top());s1.pop();}int temp = s2.top();s2.pop();return temp;}if(!s2.empty()){int temp = s2.top();s2.pop();return temp;}return -1;} };/*** Your CQueue object will be instantiated and called as such:* CQueue* obj = new CQueue();* obj->appendTail(value);* int param_2 = obj->deleteHead();*/

劍指 Offer 24. 反轉鏈表

定義一個函數,輸入一個鏈表的頭節點,反轉該鏈表并輸出反轉后鏈表的頭節點。

示例: 輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL

思路

代碼

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* reverseList(ListNode* head) {vector<int> res;ListNode *p= head;ListNode *q = head; while(p){res.push_back(p->val);p=p->next;}reverse(res.begin(),res.end());for(int i = 0;i < res.size();i++){ q->val = res[i];q = q->next; }return head;} };

劍指 Offer 30.包含min函數的棧

定義棧的數據結構,請在該類型中實現一個能夠得到棧的最小元素的 min 函數在該棧中,調用 min、push 及 pop 的時間復雜度都是 O(1)。
思路

代碼

class MinStack { public:/** initialize your data structure here. */int Min=inf;stack<int> st;MinStack() {}void push(int x) {st.push(Min);if(x<Min) Min=x;st.push(x);}void pop() {st.pop();Min = st.top();st.pop();}int top() {return st.top();}int min() {return Min;} };/*** Your MinStack object will be instantiated and called as such:* MinStack* obj = new MinStack();* obj->push(x);* obj->pop();* int param_3 = obj->top();* int param_4 = obj->min();*/

總結

以上是生活随笔為你收集整理的LeetCode详解C++版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。