Leetcode刷题笔记-1

      因为疫情没法去学校,空余时间很多,正好学习下数据结构与算法,在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;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值