LEETCODE-簡單級別

1、兩個數交換,不用temp

x = x ^ y;
y = x ^ y;
x = x ^ y;
x ^= y;
y ^= x;
x ^= y;

2、string 數字轉整形數據

string temp = "-123456";
int output = atoi(temp.c_str());
//也可以用 stoi  就不用換成char*
int output = stoi(temp);

3、string 提取某一段子string

string temp = "HELLO";
temp = temp.substr(1,2);//第一個參數是從哪個下標開始,第二個參數是取幾個字符
cout << temp;

4、string 的操作

string.insert(要插入的位置,插入的數量,插入什麼)
string.push_back();
string.pop_back();
string.back();//指向string的末尾
string.begin();//指向string的開頭
string.find();//尋找一個字符,返回其索引位置   如果沒有找到的話就到會string::npos這麼一個東西
to_string((int) temp);//將整數變成string   
for(auto c:string)//for 循環,取的是string中的每一個字符
//也可以寫成 for(char c: string)


//對於形如這樣的字符串,有空格,如果需要取每一個小段的字符串可以用istringstream函數
string temp = "alice is a good girl she is a good student";
while (words >> w) tmp.push_back(w);//生成了一個列表

reverse(temp.begin(),temp,end());//翻轉字符串

5、unordered_set的操作

用哈希表做快速查找,有可能需要定義一個新的hash函數,都是重載(), 關於set和unordered_set

struct pair_hash
{
    template<class T1, class T2>
    std::size_t operator() (const std::pair<T1, T2>& p) const
    {
        auto h1 = std::hash<T1>()(p.first);
        auto h2 = std::hash<T2>()(p.second);
        return h1^h2;
    }
};
unordered_set<int> m(nums1.begin(), nums1.end());   //初始化的方法,nums1是一個vector
m.erase(a)   //既查找了m中是否存在a,又完成了刪除a的工作

 

6、1005 K 次取反後最大化的數組和

用計數排序的方法+數組下標維護最小數的索引,很巧妙。

7、 1029 兩地調度

用數學表達式化解求極值的抽象問題,太六了。

QQå¾ç20191212114913.pngQQå¾ç20191212115343.png

8、對於函數的返回值,如果是vector可以這樣寫(350. 兩個數組的交集 II

return vector<int> (nums1.begin(),nums.begin()+k);//可以節省空間

9、記不住的vector 的基礎知識

vector<T> temp({a,b,c});//定義temp變量的時候順便往裏面放了三個元素


vector.insert():
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );

insert() 函數有以下三種用法:

在指定位置loc前插入值爲val的元素,返回指向這個元素的迭代器,
在指定位置loc前插入num個值爲val的元素
在指定位置loc前插入區間[start, end)的所有元素 .

10、返回整數的相應二進制數字1的個數

C++ 自帶的函數__builtin_popcount(x)

還可以用遞歸的方法  

bit[i]=bit[i>>1]+(i&1);

11、136. 只出現一次的數字:給定一個非空整數數組,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。

用異或運算

12、找到衆數,169題給的是這個衆數的數量大於n.size()/2,題解中的隨機法很有意思,多隨機幾次,數量越多的數中獎概率越大。第二種是Moore投票法,(但是這種方法使用的地方受限)。如果我們把衆數記爲 +1+1,把其他數記爲 -1−1,將它們全部加起來,顯然和大於 0,從結果本身我們可以看出衆數比其他數多。

13、顛倒給定的 32 位無符號整數的二進制位。

一開始想的就是int ->string ->reverse->int,麻煩。

參考一個題解,從32位整數的本質上解決的問題

uint32_t ans=0;
        //進制的本質
        int i=32;
        while(i--)
        {
            ans<<=1;
            ans+=n&1;
            n>>=1;
        }
        return ans;

這裏也有一個講位運算的文章

14、單個字符的操作

islower(char c) 是否爲小寫字母
isuppper(char c) 是否爲大寫字母
isdigit(char c) 是否爲數字
isalpha(char c) 是否爲字母
isalnum(char c) 是否爲字母或者數字
toupper(char c) 字母小轉大
tolower(char c) 字母大轉小

15、對於二進制某一位進行操作

int temp = xxxxx;
temp |= 1<<k;//對temp對應的二進制第k位進行操作。

16、不用比較符號比大小

本質是平均值法: max(a, b) = ((a + b) + abs(a - b)) / 2

主要是如何完成abs運算

以int8_t爲例:分析運算:(var ^ (var >> 7)) - (var >> 7)

var >= 0: var >> 7 => 0x00,即:(var ^ 0x00) - 0x00,異或結果爲var

var < 0: var >> 7 => 0xFF,即:(var ^ 0xFF) - 0xFF,var ^ 0xFF是在對var的全部位取反,-0xFF <=> +1, 對signed int取反加一就是取其相反數。

17、1042. 不鄰接植花

涉及到圖論的題,一般先構建鄰接表或者是鄰接矩陣。

18、設計哈希表

使用鏈地址法   705. 設計哈希集合

19、縮減搜索空間 167. 兩數之和 II - 輸入有序數組

O(n^2) ->>>>>>> O(n) 

æé¤ i = 0 çå¨é¨è§£

æ£æ¥ååæ ¼ 1, 7

 æ索空é´çåå°è¿ç¨ï¼å¨å¾ï¼æ索空é´çåå°è¿ç¨ï¼å¨å¾ï¼

20、 448. 找到所有數組中消失的數字

給定一個範圍在  1 ≤ a[i] ≤ n ( n = 數組大小 ) 的 整型數組,數組中的元素一些出現了兩次,另一些只出現一次。

找到所有在 [1, n] 範圍之間沒有出現在數組中的數字。

您能在不使用額外空間且時間複雜度爲O(n)的情況下完成這個任務嗎? 你可以假定返回的數組不算在額外空間內。

高級解法:由於1<=a[i]<=n,所以我們可以在a[i]-1這個位置統計a[i]出現的次數,同時爲了不影響其他數字的統計,只需要加數組長度就行。

一般就用 set<int> 利用唯一性檢查。

21、 最大公約數 gcd函數      1071. 字符串的最大公因子

通用模板

int gcd(int x, int y)
{
	while (y ^= x ^= y ^= x %= y);
	return x;
}

22、1018. 可被 5 整除的二進制前綴

class Solution {
public:
	vector<bool> prefixesDivBy5(vector<int>& A) {
		vector<bool> res(A.size(),false);
		int pre(0);
		vector<int> what_five_divided = { 0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4,0,1,2,3,4 };//這個地方不錯,用查表的方式代替pre%5,對5取餘數,查表比除法更快。
		for (int i = 0; i < A.size(); i++)
		{
			pre = pre << 1;
			pre += A[i];
			if (what_five_divided[pre] == 0)
			{
				res[i] = true;
			}
			pre = what_five_divided[pre];//這個地方再取餘,對於5的倍數,*2後還是5的倍數,對於餘數爲1的數,就可以把它當做1來看
		}
		return res;
	}
};

23、1089. 複寫零

如果正向遍歷找不到最優的處理方法就試試反向遍歷數組。

24、計算排列組合個數的模板,計算Cnm的

long long jiecheng(int i)
    {
        long long int tt = 1;
        for(int j = 2;j <= i;j++)
        {
            tt *= j;
        }
        return tt;
    }
    long long jiecheng(int i,int j)
    {
        long long int tt = 1;
        for(;i >= j;i--)
        {
            tt *= i;
        }
        return tt;
    }
    int cnm(int n,int m)
    {
        return jiecheng(n,n-m+1)/jiecheng(m);
    }

25、 基姆拉爾森計算公式  根據年月日 計算今天是星期幾。。。。我也是佛了

string dayOfTheWeek(int day, int month, int year) {
        if(month==1||month==2) month+=12,year--;
	int iWeek = (day+2*month+3*(month+1)/5+year+year/4-year/100+year/400)%7;                              //基姆拉爾森計算公式
       string result[]= { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"};
	return result[iWeek];
    }

26、找出數組中重複的數字。
在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。

//鴿巢原理
int findRepeatNumber(vector<int>& nums) {
        for(int i = 0;i < nums.size();++i)
        {
            if(nums[i] == i)
                continue;
            if(nums[nums[i]] == nums[i])
                return nums[i];
            int tmp = nums[i];
            nums[i] = nums[nums[i]];
            nums[tmp] = tmp;//注意這裏不要寫成nums[nums[i]] = tmp;
        }
        return 0;
    }

27、290. 單詞規律  (參考205題題解)

給定一種規律 pattern 和一個字符串 str ,判斷 str 是否遵循

相同的規律。

這裏的 遵循 指完全匹配,例如, pattern 裏的每個字母和字符串 str 中的每個非空單詞之間存在着雙向連接的對應規律。

 

28、160. 相交鏈表

跟樹一樣,得到的啓發就是如果優化不下去了,可以試試把一個數據結構接在他的末尾處,比如把一個鏈表接在另一個鏈表後面延長一下,或者是把一個子樹的根接在另一個樹結點的下面,可能會解決問題。

輸入: pattern = "abba", str = "dog cat cat dog"
輸出: true
輸入: pattern = "aaaa", str = "dog cat cat dog"
輸出: false

 複製205題題解評論區的方法:大概就是將兩個不同的字符串

將第一個出現的字母映射成 1,第二個出現的字母映射成 2

對於 egg
e -> 1
g -> 2
也就是將 egg 的 e 換成 1, g 換成 2, 就變成了 122

對於 add
a -> 1
d -> 2
也就是將 add 的 a 換成 1, d 換成 2, 就變成了 122

egg -> 122, add -> 122
都變成了 122,所以兩個字符串異構。

28、初始化一個map

map<char,int> map1={{key1,value1},{key2,value2}};

29、二分法  STL

binary_search(arr[],arr[]+size ,  indx)
/*arr[]: 數組首地址 size:數組元素個數 indx:需要查找的值*/
//lower_bound:查找第一個大於或等於某個元素的位置。
lower_bound(arr[],arr[]+size ,  indx):
/*arr[]: 數組首地址 size:數組元素個數 indx:需要查找的值*/
//upper_bound:查找第一個大於某個元素的位置。
upper_bound(arr[],arr[]+size ,  indx):
/*arr[]: 數組首地址 size:數組元素個數 indx:需要查找的值*/

lower_bound( begin,end,num,greater<type>() ):從數組的begin位置到end-1位置二分查找第一個小於或等於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。

upper_bound( begin,end,num,greater<type>() ):從數組的begin位置到end-1位置二分查找第一個小於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。

30、字符串  459. 重複的子字符串

給定一個非空的字符串,判斷它是否可以由它的一個子串重複多次構成。給定的字符串只含有小寫英文字母,並且長度不超過10000。

輸入: "abab"

輸出: True

解釋: 可由子字符串 "ab" 重複兩次構成。

假設給定字符串s可由一個子串x重複n次構成,即s=nx。
現構造新字符串t=2s,即兩個s相加,由於s=nx,則t=2nx。
去掉t的開頭與結尾兩位,則這兩處的子串被破壞掉,此時t中包含2n-2個子串。
由於t中包含2n-2個子串,s中包含n個子串,若t中包含s,則有2n-2>=n,可得n>=2,由此我們可知字符串s可由一個子串x重複至少2次構成,判定爲true;反之,若t中不包含s,則有2n-2<n,可得n<2,n只能爲1,由此我們可知字符串s=x,假定的子串就爲s本身,判定爲false。

這個思路的確好,但是無法套用其他題目

31、 我怎麼發現,把兩個輸入字符串相加也是一種思路呢?

面試題 01.09. 字符串輪轉

32、獲取map的key的方法

map<int ,int> tmp;
for (auto tt : tmp)
		cout << tt.first << " " << tt.second << endl;

33、七進制(類似十進制,二進制,就是不斷取餘)

while ( num > 0)
{
    rest = num % 7 + '0';
    num = num / 7;
    s = rest + s;
}

34、約瑟夫環的公式+生動推導。重點是關注剩下的最後一個人的位置是0,然後反推。

https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/huan-ge-jiao-du-ju-li-jie-jue-yue-se-fu-huan-by-as/

35、

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章