程序員進階之算法練習:LeetCode專場

歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~

本文由落影發表

前言

LeetCode上的題目是大公司面試常見的算法題,今天的目標是拿下5道算法題: 題目1是基于鏈表的大數加法,既考察基本數據結構的了解,又考察在處理加法過程中的邊界處理; 題目2是求數組出現頻率前k大的數字,考察思維能力,代碼很短; 題目3是給出從兩個數組中選擇數字,組成一個最大的數字,考察的是貪心的思想; 前三個都偏向于考察想法,實現的代碼都比較簡單; 題目4、5是數據結構實現題,也是大部分人比較頭疼的題目,因為需要較多的數據結構和STL實現,并且還有時間和空間的限制。

正文

1、Add Two Numbers II

題目鏈接 題目大意

給倆個鏈表,節點由0~9的數字組成,分別表示兩個數字; 求出兩個數字的和,以鏈表的形式返回。

例如
Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)7243 + 564 =7807Output: 7 -> 8 -> 0 -> 7

題目解析: 題目的意思很明顯,就是把兩個數字加起來,需要考慮進位的情況。 因為是單向的鏈表,遍歷后很難回溯,所以先把數字存到vec中。 并且為了處理方便,vec的最低位存在vec的起始部分。 于是從0開始遍歷兩個vec即可,注意考慮最后進位的情況。

復雜度解析: 時間復雜度是O(N) 空間復雜度是O(N)

struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode *ret = NULL;vector<int> vec1, vec2;sum(l1, vec1);sum(l2, vec2);int n = vec1.size(), m = vec2.size(), flag = 0;for (int i = 0; i < n || i < m; ++i) {int x = 0, y = 0;if (i < n) {x = vec1[i];}if (i < m) {y = vec2[i];}int s = x + y + flag;if (s > 9) {s -= 10;flag = 1;}else {flag = 0;}ListNode *tmp = new ListNode(s);tmp->next = ret;ret = tmp;}if (flag) {ListNode *tmp = new ListNode(1);tmp->next = ret;ret = tmp;}return ret;}void sum(ListNode* list, vector<int> &vec) {if (list->next) {sum(list->next, vec);}vec.push_back(list->val);}
};

2.Top K Frequent Elements

題目鏈接 題目大意

給出一個數組和一個數字k,返回按數字出現頻率的前k個的數字; 1 <= k <= n, n是數組大小;

 example,Given [1,1,1,2,2,3] and k = 2, return [1,2].

題目解析:

題目分為兩個步驟: 1、統計每個數字的出現次數; 2、從中選擇k個次數最多的數字;

一個簡單的做法: 用哈希表統計每個數字的出現次數; 把每個數字的出現次數和數字組成一個pair,放入優先隊列;

這樣從優先隊列中取出k個即可。

復雜度解析: 時間復雜度是O(NlogN),主要在最后的優先隊列。

其他解法: 有一個O(NlogK)的優化; 首先把隊列變成最小有限隊列, 每次pair放入優先對時,如果當前的size大于k,那么彈出top; 這樣每次的操作從O(logN)變成O(logK)。

class Solution {
public:vector<int> topKFrequent(vector<int>& nums, int k) {unordered_map<int, int> numsHash;for (int i = 0; i < nums.size(); ++i) {++numsHash[nums[i]];}priority_queue<pair<int, int>> q;for (int i = 0; i < nums.size(); ++i) {if(numsHash[nums[i]]) {q.push(make_pair(numsHash[nums[i]], nums[i]));numsHash[nums[i]] = 0;}}vector<int> ret;for (int i = 0; i < k; ++i) {ret.push_back(q.top().second);q.pop();}return ret;}
}leetcode;

3、create-maximum-number

題目鏈接 題目大意: 給出兩個數組,數組只包括0~9十個數字,長度分別為n、m; 從兩個數組中選出k個數,組成一個長度為k的數字,要求: 1、從數組n、m選擇出來的數字相對位置不變; 2、最后的數字最大; 輸出最后的數字。

 Example 1:nums1 = [3, 4, 6, 5]nums2 = [9, 1, 2, 5, 8, 3]k = 5return [9, 8, 6, 5, 3]Example 2:nums1 = [6, 7]nums2 = [6, 0, 4]k = 5return [6, 7, 6, 0, 4]

題目解析:

要求最后數字最大,那么盡可能把數字大的排在前面; 在都合法的前提下,99* 肯定比 98*要大; 那么可以按照這樣的貪心策略: 先枚舉t,t表示從數組nums1中選出t個數字,那么數組nums2中應該選出k-t個數字; 兩個數組的所有數字組成最大的數字,因為兩個數組間的數字是可以任意順序,那么只需每次選擇較大的放在前面即可。

問題簡化成,O(N)每次從數組中選出t個最大的數字; 這個可以用貪心解決: 假設數組當前枚舉到第i個,且nums[i]=x; 從左到右遍歷已經選擇的數,當遇到一個數字t,t<x時,判斷插入x后,后續是否存在合法解;如果存在則替換,否則直到最后,插入尾部;

class Solution {
public:vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {int n = (int)nums1.size(), m = (int)nums2.size();vector<int> ret(k, 0);for (int i = max(0, k - m); i <= k && i <= n; ++i) {vector<int> tmp1 = maxArray(nums1, i);vector<int> tmp2 = maxArray(nums2, k - i);vector<int> tmp = merge(tmp1, tmp2, k);if (greater(tmp, 0, ret, 0)) {ret = tmp;}}return ret;}vector<int> maxArray(vector<int> &nums, int k) {int n = (int)nums.size();vector<int> ret(k, 0);for (int i = 0, j = 0; i < n; ++i) {while (n - i + j > k && j > 0 && ret[j - 1] < nums[i]) {--j;}if (j < k) {ret[j++] = nums[i];}}return ret;}vector<int> merge(vector<int>& nums1, vector<int>& nums2, int k) {vector<int> ret(k, 0);for (int i = 0, j = 0, r = 0; r < k; ++r) {ret[r] = greater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];}return ret;}bool greater(vector<int> &nums1, int i, vector<int> &nums2, int j) {while (i < nums1.size() && j < nums2.size() && nums1[i] == nums2[j]) {++i;++j;}return j == nums2.size() || (i < nums1.size() && nums1[i] > nums2[j]);}
};

4、 Insert Delete GetRandom O(1) - Duplicates allowed

題目鏈接 題目大意: 實現一個數據結構,包括以下三個方法: 1、insert(val): 插入一個數字; 2、remove(val): 移除一個數字; 3、getRandom: O(1)隨機返回一個數字;

 Example插入數字1;collection.insert(1);插入數字1:collection.insert(1);插入數字2collection.insert(2);隨機返回數字,要求 2/3可能返回1, 1/3可能返回2;collection.getRandom();

題目解析:

插入和移除數字不麻煩,考慮如何在O(1)時間返回一個數字。 容易知道,放在數組里面可以,然后隨機返回一個位置可以實現。 增加可以在數組最末端增加; 刪除數組中間某個數字時,可以把最末端的數字放到刪除的位置上;

現在的問題是,如何快速找到數組中該刪除的某個位置; 考慮用hash來實現。 數組就是vector<pair<int, int> >; first存val,second存出現次數; 再用一個哈希map,unordered_map<int, vector> 里面存對應數字出現的位置;

class RandomizedCollection {
public:/** Initialize your data structure here. */RandomizedCollection() {}/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */bool insert(int val) {bool ret = hashMap.find(val) == hashMap.end();hashMap[val].push_back(randVec.size());randVec.push_back(make_pair(val, hashMap[val].size() - 1));return ret;}/** Removes a value from the collection. Returns true if the collection contained the specified element. */bool remove(int val) {bool ret = hashMap.find(val) != hashMap.end();if (ret) {auto last = randVec.back();hashMap[last.first][last.second] = hashMap[val].back();randVec[hashMap[val].back()] = last;hashMap[val].pop_back();if (hashMap[val].empty()) {hashMap.erase(val);}randVec.pop_back();}return ret;}/** Get a random element from the collection. */int getRandom() {return randVec[rand() % randVec.size()].first;}private:unordered_map<int, vector<int>> hashMap;vector<pair<int, int>> randVec;
}leetcode;

5、 All O`one Data Structure

題目鏈接 題目大意

實現一個數據結構,要求: 1、Inc(Key) - Inserts a new key with value 1. Or increments an existing key by 1. Key is guaranteed to be a non-empty string. 2、Dec(Key) - If Key's value is 1, remove it from the data structure. Otherwise decrements an existing key by 1. If the key does not exist, this function does nothing. Key is guaranteed to be a non-empty string. 3、GetMaxKey() - Returns one of the keys with maximal value. If no element exists, return an empty string "". 4、GetMinKey() - Returns one of the keys with minimal value. If no element exists, return an empty string "".

要求所有的數據結構的時間復雜度是O(1);

題目解析:

在不考慮復雜度的前提下,樸素做法是遍歷,O(N); 簡單的優化,用map來維護優先隊列,操作1、2先獲取key值,更新完重新插入;操作3、4直接拿隊列top;每個操作的復雜度是O(LogN);

題目要求是O(1),那么必然不能使用樹類型的結構,應該利用題目特性,配合hash以及貪心來實現。

假設有一個key-hash表,來存key的對應值。 操作1、先看keyHash里面是否有key,有則+1,無則插入; 操作2、先看keyHash里面是否有key,有則-1,無則Nothing;

為了維護最值,引入鏈表list,里面所有的元素是從小到大;每個元素是一個桶,桶里放著值相同的key; 操作3、直接獲取list頭元素的值; 操作4、直接獲取list尾元素的值;

同時,操作1、2在操作的過程中,需要把當前key值從list對應的桶里移除,放到上一個或者下一個桶里,或者丟棄。 為了實現O(1)獲取key所在位置,可以用iter-hash來維護key所對應元素的迭代器。

struct Bucket {int value;unordered_set<string> keys;
};class AllOne {
public:list<Bucket> buckets;unordered_map<string, list<Bucket>::iterator> bucketOfKey;/** Initialize your data structure here. */AllOne() {}/** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */void inc(string key) {if (bucketOfKey.find(key) == bucketOfKey.end()) {bucketOfKey[key] = buckets.insert(buckets.begin(), {0, {key}});}auto next = bucketOfKey[key], bucket = next++;if (next == buckets.end() || next->value > bucket->value + 1) {next = buckets.insert(next, {bucket->value+1, {}});}next->keys.insert(key);bucketOfKey[key] = next;bucket->keys.erase(key);if (bucket->keys.empty()) {buckets.erase(bucket);}}/** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */void dec(string key) {if (bucketOfKey.find(key) == bucketOfKey.end()) {return ;}auto pre = bucketOfKey[key], bucket = pre;if (pre != buckets.begin()) {--pre;}bucketOfKey.erase(key);if (bucket->value > 1) {if (bucket == buckets.begin() || pre->value < bucket->value - 1) {pre = buckets.insert(bucket, {bucket->value - 1, {}});}pre->keys.insert(key);bucketOfKey[key] = pre;}bucket->keys.erase(key);if (bucket->keys.empty()) {buckets.erase(bucket);}}/** Returns one of the keys with maximal value. */string getMaxKey() {return buckets.empty() ? "" : *(buckets.rbegin()->keys.begin());}/** Returns one of the keys with Minimal value. */string getMinKey() {return buckets.empty() ? "" : *(buckets.begin()->keys.begin());}
}leetcode;

總結

這5個題目如果都能獨立完成,那么水平已經可以足以應付國內各大企業的算法面。 算法重在勤思多練,埋怨公司出算法題是沒用的,多花時間準備才是正道。

此文已由作者授權騰訊云+社區發布,更多原文請點擊

搜索關注公眾號「云加社區」,第一時間獲取技術干貨,關注后回復1024 送你一份技術課程大禮包!

轉載于:https://www.cnblogs.com/qcloud1001/p/10021759.html

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

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

相關文章

vim 安裝vim-prettier

1、在.vimrc中添加 配置沒有安裝成功的話 git clone https://github.com/prettier/vim-prettier Plug prettier/vim-prettier, { do: yarn install, for: [javascript, typescript, css, less, scss, json, graphql, markdown, vue, yaml, html, php] } let g:prettier#aut…

詳解Mysql中的JSON系列操作函數

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、方法羅列&#xff1a; 分類 函數 描述創建jsonjson_array 創建json數組json_object 創建json對象 json_quote 將json轉成json字符串…

WEB/H5性能優化總結

我們今天來說說前端圖形渲染優化&#xff0c;因為我接下來的時間可能要開始研究webgl方面的東西&#xff0c;所以就在這里把之前做過的H5做一個總結&#xff0c;現同步發布于GERRY_BLOG&#xff0c;TiMiGerry-知乎&#xff0c;轉載請保留鏈接。靜態資源-圖片 一 、圖片格式JPEG…

C語言數組參數與指針參數

我們都知道參數分為形參和實參。形參是指聲明或定義函數時的參數&#xff0c;而實參是在調用函數時主調函數傳遞過來的實際值。 一、一維數組參數 1、能否向函數傳遞一個數組&#xff1f;看例子&#xff1a;void fun(char a[10]){char c a[3];}intmain(){char b[10] “abcd…

maven文件結構

pom.xml 用于maven的配置文件 /src 源代碼目錄 /src/main 工程源代碼目錄 /src/main/java 工程java源代碼目錄 /src/main/resource 工程的資源目錄 /src/test 單元測試目錄 /src/test/java /target 輸出目錄&#xff0c;所有的輸出都存放在這個目錄下 /target/classes 編譯之…

php如何使用高階函數

1、首先學會數組轉集合的方式 &#xff08;1&#xff09;使用collect函數 $arr [1, 2, 3, 4, 5]; $collect collect($arr); &#xff08;2&#xff09;使用array_map函數 $arr [1, 2, 3, 4, 5]; $collect array_map(function($item){ return $item *…

Git 使用,命令說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. D:\ChengXu\git\Git中雙擊Git Bash啟動git窗口。 2. 這條不能放到博客&#xff0c;是我的賬號密碼。 3. 添加&#xff1a; git add …

2017ACM/ICPC亞洲區沈陽站 C Hdu-6219 Empty Convex Polygons 計算幾何 最大空凸包

題面 題意:給你一堆點,求一個最大面積的空凸包,里面沒有點. 題解:紅書板子,照抄完事,因為題目給的都是整點,所以最后答案一定是.5或者.0結尾,不用對答案多做處理 1 #include<bits/stdc.h>2 #define N 553 using namespace std;4 struct rec5 {6 double x,y;7 };8 rec…

python讀xml文件

# -*- coding:utf-8 -*- import jsonimport requestsimport oscurpathos.path.dirname(os.path.realpath(__file__))xmlpathos.path.join(curpath,read1.xml)with open(xmlpath,encoding"utf-8") as fp: bodyfp.read() print(body)轉載于:https://www.cnblogs.…

C語言數組應用

一、數組的內存布局 先看下面的例子&#xff1a;int a[5];所有人都明白這里定義了一個數組&#xff0c;其包含了5 個int 型的數據。我們可以用a[0],a[1]等來訪問數組里面的每一個元素&#xff0c;那么這些元素的名字就是a[0],a[1]…嗎&#xff1f;看下面的示意圖&#xff1a; 如…

Installation failed, deleting ./composer.json.安裝phpunit報錯解決方案

是因為你沒有裝全局的phpunit&#xff0c;安裝命令 composer global require phpunit/phpunit 之后你輸入 composer require --dev phpunit/phpunit 就發現你安裝成功了

MyBatis在Oracle中插入數據并返回主鍵的問題解決

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 前言&#xff1a;我早期用過這個方法&#xff0c;但是返回的依舊是影響行數&#xff0c;不是主鍵。 只是這種寫法可以達到我要的效果&a…

在 Intellij IDEA 里使用 OpenJFX (JavaFX)

2019獨角獸企業重金招聘Python工程師標準>>> JDK 11 把 JavaFX 剝離了出來&#xff0c;形成了單獨且開源的 OpenJFX 模塊。 本文的目的是通過簡單的例子解釋這一變化對使用 JavaFX 所造成的影響&#xff0c;并找到一種在 IDEA 2018.2 上使用它的辦法。 首先&#xf…

使用phpunit新建項目

1、mkdir test-project 新建一個test-project 2、cd test-project 跑到文件夾中 3、實例化git git init 4、新建phpunit項目 composer require --dev phpunit/phpunit 5、使用gi實例化.gitignore gi composer>.gitignore (如果沒有安裝gi&#xff0c;請使用命令ec…

如何解決eclipse里面tomcat 8080端口被占用

很多時候運行tomcat 的時候總是會提示tomcat 的端口被占用 但是任務管理器里面還找不到是哪個端口被占用了 因此很多人就重新配置tomcat 或者去修改tomcat的端口號 &#xff0c;其實這么做太麻煩了 &#xff0c;小弟在這里告訴你一個非常簡單的方法。 1.在開始菜單中選擇運行 …

Selenium UI 舉例 getCssValue

selenium jar包中&#xff0c;在WebElement的接口中&#xff0c; String getCssValue(String var1);可以通過標簽&#xff0c;獲取對應的css值。具體要怎么用呢&#xff0c;如下&#xff1a; WebElement baidu driver.findElement(By.id("su"));su.getCssValue(&quo…

java集合框架中contains(),containsKey()和containsValue()的用法

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 java集合框架中contains(),containsKey()和containsValue()的用法&#xff1a; List集合的contains()方法用于判斷集合中包不包含某個元…

敏捷視頻

規模化極限編程的關鍵抓手&#xff1a;驗收條件https://mp.weixin.qq.com/s/aHlSxpMx7DTQXaoEgcAQ3g 5分鐘讓你子解持續集成https://www.bilibili.com/video/BV1SK411W77W/?spm_id_fromtrigger_reload 5分鐘讓你學會返工率降低1倍的神技--開卡、驗卡https://www.bilibili.com/…

提問的智慧

提問的智慧轉載于:https://www.cnblogs.com/whigym/p/10028642.html

C語言指針和數組概述

幾乎每次講課講到指針和數組時&#xff0c;我總會反復不停的問學生&#xff1a;到底什么是指針&#xff1f;什么是數組&#xff1f;他們之間到底是什么樣的關系。從幾乎沒人能回答明白到幾乎都能回答明白&#xff0c;需要經歷一段“慘絕人寰”的痛。指針是C/C的精華&#xff0c…