【C++】刷题强训(day12)--删除公共字符、两个链表的第一个公共节点、mari和shiny

目录

1、删除公共字符

1.2 思路

1.3 代码实现

2、两个链表的公共节点

2.1 题目

2.2 思路

 2.3 代码实现

 方法一:对齐

方法二:公共端点法

3、mari和shiny 

3.1 题目

3.2 思路

3.3 代码实现


刷题汇总:传送门!

1、删除公共字符

1.2 思路

暴力解法就是,遍历一遍第一个字符串,看看第二个字符串中有没有,没有则尾插到新的字符串中,最后输出即可。优化一下,可以采用hash表标记第二个中的字符串,然后只需遍历一遍第一个字符串,如果hash中已存在,则是相同字符,不存在,则插入到新的字符串中,最后输出即可;

当然了,也可以不创建新的字符串存储,直接打印也可以

1.3 代码实现

#include <iostream>
using namespace std;

int main() 
{
    string str1,str2;
    getline(cin,str1);
    getline(cin,str2);

    bool hash[300] = {0};

    int n = str1.size(),m = str2.size();
    for(int i = 0;i < m;i++)
        hash[str2[i]] = true;
    
   //string ret;
   for(auto x : str1)
   {
        if(!hash[x])
            cout << x;
            //ret += x;  
   }
    //cout << ret << endl;

    return 0;    
}

2、两个链表的公共节点

2.1 题目

2.2 思路

读完题我们知道,这道题让我们返回两个链表第一次相遇的公共节点,没有则返回空,这里有两种解题思路。

第一种,将两个链表对齐,将较长的链表去除多余的非公共部分,是的两个链表一样长,在同时遍历两个链表,当两个链表节点相同,并且值相同的时候,那么这个节点就是第一个公共节点

第二种, 两个链表如果有公共节点的话,那么他们所遍历全部节点所走的路程是相同的,各自的非公共部分+公共部分+对方的非公共部分,同时从头开始遍历,遍历结束的位置就是第一个公共节点的端点(如果存在公共节点)

 

 2.3 代码实现

 方法一:对齐

class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) 
	{
		int len1 = 0,len2 = 0;
		ListNode* cur1 = pHead1,*cur2 = pHead2;
		//计算差值
		while(cur1)
		{
			len1++;
			cur1 = cur1->next;
		}
		while(cur2)
		{
			len2++;
			cur2 = cur2->next;
		}
		int count = abs(len1-len2);
		if(len1 >= len2)
		{
			while(count--)
				pHead1 = pHead1->next;
			cur1 = pHead1,cur2 = pHead2;
			while(cur1 != cur2 && cur1->val != cur2->val)
			{
				cur1 = cur1->next;
				cur2 = cur2->next;
			}
		}
		else 
		{
			while(count--)
				pHead2 = pHead2->next;
			cur1 = pHead1,cur2 = pHead2;
			while(cur1 != cur2 && cur1->val != cur2->val)
			{
				cur1 = cur1->next;
				cur2 = cur2->next;
			}
		}
		return cur1;
    }
};

方法二:公共端点法

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) 
	{
		ListNode* cur1 = pHead1;
		ListNode* cur2 = pHead2;
		while(cur1 != cur2)
		{
			cur1 = cur1 != nullptr ? cur1->next : pHead1;
			cur2 = cur2 != nullptr ? cur2->next : pHead2;
		}
		return cur1;
    }
};

3、mari和shiny 

3.1 题目

3.2 思路

根据题目知道要我们求有多少个 shy ,其中这一段 's' 'h' 'y' 并不一定是连续的,可自由组成子序列shy。再根据示例可知每一个 's' 'h' 'y'都可以不重复的随意拼接。shy由sh和y决定,而sh由s和h决定,那么可以使用动态规划思想。

3.3 代码实现

注意使用long long 防止越界。

#include<iostream>
using namespace std;

int main()
{
    int n = 0;
    cin >> n;
    string str;
    cin >> str;
    long long s = 0, h = 0,y = 0;
    for(int i =0;i < n;i++)
    {
        char ch = str[i];
        if(ch == 's')
            s++;
        else if(ch == 'h')
            h += s;
        else if(ch == 'y')
            y += h;
    }
    cout << y << endl;
    
    return 0;
}


本篇完,下篇见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值