Leetcode刷题防忘录(九)

本文深入探讨LeetCode上的经典算法题目,包括字典辅助的anagrams问题,strStr字符串匹配,Z字形字符串转换,动态规划求解最长回文子串,及寻找字符串数组中的最长公共前缀。通过详细代码示例,讲解每种算法的实现思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

anagrams(字典,中等)

implement-strstr(遍历,简单)

zigzag-conversion(二维矩阵,中等)

longest-palindromic-substring(动态规划,中等)

longest-common-prefix(遍历,简单)


anagrams(字典,中等)

给出一个字符串数组,返回所有互为“换位词(anagrams)”的字符串的组合。(换位词就是包含相同字母,但字母顺序可能不同的字符串)

For example:

Input: ["tea","and","ate","eat","den"]

Output:   ["tea","ate","eat"]

思路

用字典来辅助,将每个值都排列好顺序后存入字典,如果下一个值排好序列之后和字典已经存进去的数相等,就说明这俩互为换位词。另外,字典的find用法,为true表示在字典中找到了重复的值,为false就是没找到。

m.find(key)!=m.end()

“-2”代表占位符,表示这个值之前已经遍历过了,不需要再考察了. 

完整code

class Solution {
public:
    vector<string> anagrams(vector<string> &strs) {
        vector<string>res;
        unordered_map<string,int>m;
       for(int i=0;i<strs.size();i++)
       {
         string key=strs[i];
         sort(key.begin(),key.end());
           if(m.find(key)!=m.end())
           {
               if(m[key]!=-2)
                   res.push_back(strs[m[key]]);
               m[key]=-2;
               res.push_back(strs[i]);
           }
           else
               m[key]=i;
       }
       return res;
    }
};

implement-strstr(遍历,简单)

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1

思路

逐个元素对比,只要找到开头一样的,然后,就把needle循环对比一遍。

完整code

class Solution {
public:
    char *strStr(char *haystack, char *needle) {
         if(needle==NULL||haystack==NULL)
            return NULL;
        if(*haystack=='\0'&&*needle=='\0')
            return haystack;
         
        for(char *p=haystack;*p!='\0';p++)
        {
            char *l=p;
            char *s=needle;
            while(*l!='\0'&&*s!='\0'&&*l==*s)
            {
                l++;
                s++;
            }
            if(*s=='\0')
                return p;
        }
        return NULL;
         
    }
};

zigzag-conversion(二维矩阵,中等)

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

L   C   I   R
E T O E S I I G
E   D   H   N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);
示例 1:

输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"
示例 2:

输入: s = "LEETCODEISHIRING", numRows = 4
输出: "LDREOEIIECIHNTSG"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

思路

这个和二维矩阵很相似,都是找关键位置和对应关系,进行移动,分三种情况,拐头

				while (k < len)
				{
					res += s[k];
					k += 2 * nRows - 2;
				}

和Z字中间的元素移动,

 

			bool flag = true;
			while (k < len)
			{
				res += s[k];
				k += flag ? 2 * (nRows - i - 1) : 2 * i;
				flag =!flag;
			}

设了一个标志位,表明后两种不同的区分。那对应关系是怎么得的,那我也说不清了,反正,就是有对应关系。 

完整code

class Solution {
public:
	string convert(string s, int nRows) {
		if (nRows <= 1) return s;
		string res = "";
		int len = s.size();
		for (int i = 0; i < nRows; i++)
		{
			int k = i;
			if (i == 0 || i == nRows - 1)
			{
				while (k < len)
				{
					res += s[k];
					k += 2 * nRows - 2;
				}
			}
			bool flag = true;
			while (k < len)
			{
				res += s[k];
				k += flag ? 2 * (nRows - i - 1) : 2 * i;
				flag =!flag;
			}
		}
		return res;
	}
};

longest-palindromic-substring(动态规划,中等)

给定一个字符串s,找到其中最长的回文子序列。可以假设s的最大长度为1000。

示例 1:
输入:"bbbab"  输出:4
一个可能的最长回文子序列为 "bbbb"。

示例 2:
输入:"cbbd"    输出:2
一个可能的最长回文子序列为 "bb"。

思路

fill_n函数的作用是:参数包括 : 一个迭代器,一个计数器以及一个值。该函数从迭代器指向的元素开始,将指定数量的元素设置为给定的值。

 

完整code

class Solution {
public:
    // 最长回文串,使用dp
    string longestPalindrome(string str)
    {
     int n = str.length();
    if(n==0) return "";
    bool dp[n][n];
    fill_n(&dp[0][0],n*n,false);
    int left=0,right=0,maxLen = 0;
    for(int j=0;j<n;j++)
    {
      dp[j][j] = true;
      for(int i=0;i<j;i++)
      {
          dp[i][j] = (str[i] == str[j] && (j-i < 2 || dp[i+1][j-1]));
          if(dp[i][j] && (j-i+1 > maxLen))
          {
              left = i;
              right = j;
              maxLen = j-i+1;
          }
      }
    }
    return str.substr(left,right-left+1);
    }
};

longest-common-prefix(遍历,简单)

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""。

示例 1:

输入: ["flower","flow","flight"]    输出: "fl"
示例 2:

输入: ["dog","racecar","car"]    输出: ""
解释: 输入不存在公共前缀。

思路

先将开头首个字符串给作为待比较的值,让后面的每个字符都跟这个比较,将不重复的都删除。

如果说,就这一个字符串和其他的都没有公共部分,而其他的都有,算啥?算没公共字串,因为找公共字串是找所有的,少一个都不行。

完整code

class Solution {
public:
	string longestCommonPrefix(vector<string>& strs) {
		if (strs.empty()) return "";
		string res = strs[0];
		for (int i = 0; i < strs.size(); i++)
		{
			for (int j = 0; j < res.size(); j++)
			{
				if (res[j] == strs[i][j])
					continue;
				else
				{
					res.erase(j);
					break;
				}
			}
		}
		return res;
	}
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值