1.两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
因为每一位数字都是逆序的,所以可以直接使用数学方法进行相加,并且需要加上上一位得出的进位,最后注意如果最后一位的进位大于0,则还需要加上一位。
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* head=NULL;
ListNode* tail=NULL;
int carry=0;//进位
while(l1||l2)
{
int num1=l1?l1->val:0;
int num2=l2?l2->val:0;
int sum = num1+num2+carry;
if(head==NULL)
{
head = tail = new ListNode(sum%10);
}else
{
tail->next = new ListNode(sum%10);
tail = tail->next;
}
carry=sum/10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if(carry>0){
tail->next = new ListNode(carry);
tail = tail->next;
}
return head;
}
2.无重复字符的最长子串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
使用两个指针,第一个指针初始位置为0,第二个指针从第一个指针开始不断往后遍历字符串,可以采用哈希表存储遍历过的字符串及其下标,不重复时最长子串长度加+1,当出现重复时,找到哈希表中该重复元素的下标,将第一个指针位置设置为该下标+1,再将当前最长子串长度与之前的做比较,即可得出最长子串长度。
int lengthOfLongestSubstring(string s) {
if(s.size()==0)
{return 0;}
int max=1;
int k=0;
for(int i=0;i<s.size();i++)
{
int maxn=1;
for(int j=k;j<i;j++)
{
if(s[i]==s[j])
{
k=j+1;
break;
}
maxn++;
}
if(maxn>max)
{
max=maxn;
}
}
return max;
}
3.最长回文子串
给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
采用动态规划的方法如果一个子串是回文串,那么去掉第一个和最后一个元素时其也是回文串。dp[i][j]表示j到i之间的子串是否为回文串,那么当s[i]=s[j]时dp[i][j]=dp[i-1][j+1];
string longestPalindrome(string s) {
int maxlen=1;
int begin=0;
bool dp[1050][1050];
for(int i=0;i<s.size();i++)
{
dp[i][i]=true;
}
for(int i=0;i<s.size();i++)
{
for(int j=0;j<=i;j++)
{
if(s[i]!=s[j])
{
dp[i][j]=false;
}else{
if(i-j<3)
{
dp[i][j]=true;
}else{
dp[i][j]=dp[i-1][j+1];
}
}
if(dp[i][j]&&i-j+1>maxlen)
{
maxlen=i-j+1;
begin=j;
}
}
}
return s.substr(begin,maxlen);
}
4.整数反转
给你一个 32 位的有符号整数 x
,返回将 x
中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1]
,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
对原整数进行取模运算得到x末尾的数字,重复该过程即可实现x中的数字反转。再和2147483647,-214748364比较即可。但环境不允许存储64位整数,故可以将反转后的数除以10和-2^31/10,2^31-1/10比较即可,此时还需要将最后一次弹出来的数和7和-8进行比较,最后便可实现溢出判断。
int reverse(int x) {
int num=0;
while(x){
int tmp = x%10;
if(num>214748364||(num==214748364&&tmp>7))
{
return 0;
}
if(num<-214748364||num==-214748364&&tmp<-8)
{
return 0;
}
num=num*10+tmp;
x=x/10;
}
return num;
}
5.有效的括号
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
解法:依靠数据结构中的栈来解决,从左到右遍历字符串,当栈为空时入栈,符号为左括号时直接入栈,为右括号时判断是否和栈顶的左括号相对赢,成功则返回栈顶元素出栈,失败和返回false。当字符串长度为奇数时,直接返回false,因为需保证每个括号都有另一个括号与之相对应。
bool isValid(string s) {
if(s.size()%2==1)
{
return false;
}
stack<char>mystack;
for(int i=0;i<s.size();i++)
{
if(mystack.empty())
{
mystack.push(s[i]);
}else{
char c=s[i];
if(c=='{'||c=='['||c=='(')
{
mystack.push(s[i]);
}
if(c=='}')
{
if(mystack.top()=='{')
{
mystack.pop();
}else{
return false;
}
}
if(c==']')
{
if(mystack.top()=='[')
{
mystack.pop();
}else{
return false;
}
}
if(c==')')
{
if(mystack.top()=='(')
{
mystack.pop();
}else{
return false;
}
}
}
}
if(mystack.empty())
{
return true;
}else{
return false;
}
}
6.合并两个有序单链表
采用递归的方式,当l1或l2为空时,直接返回l1或l2,当l1中的值大于l2时返回l2,l2->next进行递归,当l2中的值大于l1时,l1->next进行递归。
ListNode* mergeTwolist(listNode *l1,ListNode *l2){
if(l1==NULL)
{return l1;}else if(l2==NULL)
{return l2;}else if(l1->val<l2->val){
l1->next=mergeTwolist(l1->next,l2);
return l1;
}else
{
l2->next=mergeTwolist(l1,l2->next)
return l2;
}
}