因为疫情没法去学校,空余时间很多,正好学习下数据结构与算法,在leetcode上看看题,记录一下学到的一些新东西。
1.关于整数反转的问题,这个不难,通过取整和取余运算就可以实现颠倒
代码如下:
当然也有其他的版本,这只是我的想法。
int reverse(int x) {
long res = 0;
if (x<INT_MIN || x>INT_MAX)//防止溢出
return 0;
if (x<0)
return -reverse(-x);//负数时的处理方法
while (x>0)
{
int temp = 0;
temp = x % 10;//取余得到最低位的数值
x /= 10;
res = 10 * res + temp;
}
if (res>INT_MAX)//防止溢出
return 0;
else
return (int)res;
}
2.二进制的翻转
由上面的问题所引申的另一种情况。
因为我对位操作不了解,只能借鉴别人的代码,代码如下:
uint32_t reverseBits(uint32_t n)
{
uint32_t res=0;
for(int i=0;i<32;i++)
{
res<<=1;//左移一位并赋值
res|=(n&1);//n和1求与操作再与res求或操作并赋值给res
n>>=1;//右移一位并赋值
}
return res;
}
res初始值为0,左移一位仍为0,n与1实质上是得到n的最低位,因为1可以写成00000001,0与任何数求与仍为0,1与任意数求与都不改变原来的值,又res=0,res|=(n&1)就是将n的最低位赋值给res的最低位,然后n右移一位就是将原来的最低位去除,用紧接着的一位代替,此时res左移一位后最低位为0,反复前面的操作就能实现二进制的颠倒。
记录几个常用的位操作符号:
①>>= 右移赋值
int i=4; //写成二进制为0100
int i>>=2; //向右移两位,结果为0001,输出结果为1
int i>>=1;//右移一位,结果为0010,输出结果为2,右移一位即取原来值得一半
//假设原始值为n,将其右移m位,得到的值为n/(2^m)(在能整除得情况下)
②<<= 左移操作
int i=4;//二进制位0100
int i<<=2;//左移两位,结果为0001 0000,输出结果为16
//假设原始值为n,将其左移m位,得到的值为n*(2^m)
③&= 按位与后赋值
与操作是在二进制下,两数都为1时才为1,其他情况都为0
int i = 4;//0100
i &= 2;//0100 & 0010
cout << i;//输出结果为0000
④^= 按位异或再赋值
异或运算准则:相同为0,不同为1
int i = 4;//0100
i ^= 2;//0100 ^ 0010
cout << i;//输出结果为0110
⑤|= 按位或再赋值
或运算准则:有一个为1结果都为1
int i = 4;//0100
i |= 2;//0100 | 0010
cout << i;//输出结果为0110
3.找出无重复子串得最大长度
我所能理解的一种解法是利用滑动窗口,即假设字符串为abcabcbb,第一次进行操作时,将窗口左右边界都设为0,然后右边界加1,遍历这个区间内的字符,若有重复,输出重复的字符的下标,并将左边这个重复的字符剔除,即左边界加1,循环此过程,其实现代码如下:
int GetPosNum(int left, int right, const string& s, char target)
{
for (int i = left; i < right; i++)
{
if (s[i] == target)
return i;
}
return -1;
}
int lengthOfLongestSubstring(string s)
{
const int len = s.length();
int i = 0;
int j = 0;
int max_len = 0;
while (j < len)
{
int pos = GetPosNum(i,j,s,s[j]);
if (pos == -1)//说明在窗口范围内没有相同的字符,右边界右移一位
j++;
else
{
max_len =(j-i) > max_len ? (j-i) : max_len;
i = pos + 1;
}
}
max_len = (j - i) > max_len ? (j - i) : max_len;
return max_len;
}
还有一种简洁的解法,用到了C++ STL库的unordered_set,用到这个时必须包含头文件**#include<unordered_set>**。C++ 11中对unordered_set描述大体如下:无序集合容器(unordered_set)是一个存储唯一(unique,即无重复)的关联容器(Associative container),容器中的元素无特别的秩序关系,该容器允许基于值的快速元素检索,同时也支持正向迭代。 在一个unordered_set内部,元素不会按任何顺序排序,而是通过元素值的hash值将元素分组放置到各个槽(Bucker,也可以译为“桶”),这样就能通过元素值快速访问各个对应的元素(均摊耗时为O(1))。
int lengthOfLongestSubstring(string s) {
if (s.size() == 0) return 0;
unordered_set<char> lookup;
int maxStr = 0;
int left = 0;
for (int i = 0; i < s.size(); i++) {
while (lookup.find(s[i]) != lookup.end())
{
lookup.erase(s[left]);
left++;
}
maxStr = max(maxStr, i - left + 1);
lookup.insert(s[i]);
}
return maxStr;
}