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
    std::size_t operator() (const std::pair& p) const
    {
        auto h1 = std::hash()(p.first);
        auto h2 = std::hash()(p.second);
        return h1^h2;
    }
};
unordered_set m(nums1.begin(), nums1.end());   //初始化的方法,nums1是一个vector
m.erase(a)   //既查找了m中是否存在a,又完成了删除a的工作

 

6、1005 K 次取反后最大化的数组和

用计数排序的方法+数组下标维护最小数的索引,很巧妙。

7、 1029 两地调度

用数学表达式化解求极值的抽象问题,太六了。

LEETCODE-简单级别_第1张图片LEETCODE-简单级别_第2张图片

8、对于函数的返回值,如果是vector可以这样写(350. 两个数组的交集 II

return vector (nums1.begin(),nums.begin()+k);//可以节省空间

9、记不住的vector 的基础知识

vector 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. 只出现一次的数字:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

用异或运算

LEETCODE-简单级别_第3张图片

12、找到众数,169题给的是这个众数的数量大于n.size()/2,题解中的随机法很有意思,多随机几次,数量越多的数中奖概率越大。第二种是Moore投票法,(但是这种方法使用的地方受限)。如果我们把众数记为 +1+1,把其他数记为 -1−1,将它们全部加起来,显然和大于 0,从结果本身我们可以看出众数比其他数多。

LEETCODE-简单级别_第4张图片

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<

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) 

LEETCODE-简单级别_第5张图片

LEETCODE-简单级别_第6张图片

 LEETCODE-简单级别_第7张图片LEETCODE-简单级别_第8张图片

20、 448. 找到所有数组中消失的数字

给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。

找到所有在 [1, n] 范围之间没有出现在数组中的数字。

您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。

高级解法:由于1<=a[i]<=n,所以我们可以在a[i]-1这个位置统计a[i]出现的次数,同时为了不影响其他数字的统计,只需要加数组长度就行。

一般就用 set 利用唯一性检查。

21、 最大公约数 gcd函数      1071. 字符串的最大公因子

通用模板

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

22、1018. 可被 5 整除的二进制前缀

class Solution {
public:
	vector prefixesDivBy5(vector& A) {
		vector res(A.size(),false);
		int pre(0);
		vector 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& 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 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() ):从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num,greater() ):从数组的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

这个思路的确好,但是无法套用其他题目

31、 我怎么发现,把两个输入字符串相加也是一种思路呢?

面试题 01.09. 字符串轮转

32、获取map的key的方法

map 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、

你可能感兴趣的:(lEETCODE刷题)