力扣刷题—字符串

1.14. 最长公共前缀

最长公共前缀

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

  • 如果不存在公共前缀,返回空字符串 “”。
    在这里插入图片描述

1.解题思路(横向对比)

  • 1.新建变量comm储存当前的公共前缀,初始化为字符串数组的元素;
  • 2.对每一个字符串s进行遍历,comm与s的字符从前向后进行比较,遇到不同的时跳出;
  • 3.当公共部分长度为0时,跳出。
class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs==null || strs.length==0) return "";
        1.暂时存公共前缀
        String comm = strs[0];
        2.循环队列内的所有 字符串
        for (String s:strs) {
            int index = 0;
            int len = Math.min(comm.length() ,s.length());
            3.当满足index<最小长度  且 字符串相同下标处的 字符相同  则 index++
            while (index<len && (comm.charAt(index) == s.charAt(index))){index++;}
            4.0~index-1 之内的数据,即为本次公共字符串
            comm = comm.substring(0,index);
            5.当公共部分为0时,提前跳出
            if (comm.length()==0)
                return "";
        }
        6.返回公共前缀
        return comm;
    }
}

2.344. 反转字符串

344. 反转字符串

  • 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
  • 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
  • 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
    在这里插入图片描述

1.解题思路(交换)

  • 1.使用swap函数进行前后交换,从两头向中间走。
class Solution {
    public void reverseString(char[] s) {
        if (s==null || s.length==0 || s.length==1) return;

        for (int i = 0; i < s.length/2; i++) {
            swap(s,i,s.length-i-1);
        }
    }
    public void swap (char[] chars ,int i,int j){
        Character temp = chars[i];
        chars[i] = chars[j];
        chars[j] = temp;
    } 
}

3. 557. 反转字符串中的单词 III

557. 反转字符串中的单词 III

  • 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
    在这里插入图片描述

1.解题思路

  • 1.先把String以空格为间隔划分为单个字符串数组strs;
  • 2.对strs中的每个元素进行反转,同时进行字符串拼接;
  • 时间复杂度:O(N)
  • 空间复杂度:O(N)
class Solution {
    public String reverseWords(String s) {
    	1.去除特殊情况
        if (s==null || s.length()==0 || s.length()==1) return s;
        2.按空格划分成字符串数组
        String[] strs = s.split(" ");
        StringBuilder sb = new StringBuilder();
        3.反转的同时进行拼接
        for (int i = 0; i < strs.length; i++) {
            sb.append(reverseSingle(strs[i]));
            sb.append(" ");
        }
        4.删除最后一个空格!!!!
        sb.deleteCharAt(sb.length()-1);
        return new String(sb);
    }
    2.对单个字符串进行反转
    public String reverseSingle(String s){
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length/2; i++) {
            swap(chars,i,chars.length-1-i);
        }
        return new String(chars);
    }
    public void swap (char[] chars ,int i,int j){
        Character temp = chars[i];
        chars[i] = chars[j];
        chars[j] = temp;
    }
}

4.3. 无重复字符的最长【子串】

  • 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

在这里插入图片描述

1.解题思路(滑动窗口解法)

  • 1.求的是最长公共子串,而不是子序列
  • 2.滑动窗口法,保证left、right指针之间的字符串是无重复的;
左指针left更新的问题
  • left = Math.max(map.get(s.charAt(right))+1,left);

eg:abcddbef

  • 1.在发现d重复时,left由0更新为4;
  • 2.在发现b重复时,新left取:旧left=4、上一个b下标=1,两者的最大值,即:4。
class Solution {
    public int lengthOfLongestSubstring(String s) {
    	0.排除特殊情况
        if(s==null || s.length()==0) return 0;
        1.Map存储字符、及其对应下标
        Map<Character,Integer> map = new HashMap<>();
        2.定义指针left、 最大长度max
        int left=0,max=0;
        int len = s.length();
        3.右指针向后滑动
        for (int right = 0; right < len; ++right) {
        	4.当遇到重复的元素
            if (map.containsKey(s.charAt(right))){
                5.更新左指针 left
                left = Math.max(map.get(s.charAt(right))+1,left);
            }
            map.put(s.charAt(right),right);
            动态获取最大长度max
            max = Math.max(max,right-left+1);
        }
        return max;
    }
}

5.无重复字符的最长【子序列】(上一题的子串,改为子序列)

1.解题思路(回溯算法)

class Solution02 {
    int resMax;
    public int lengthOfLongestSubstring(String s) {
        if(s==null || s.length()==0) return 0;
        char[] chars = s.toCharArray();
        Set<Character> set = new HashSet<>();
        resMax = 0;
        backTrack(chars,0,set);
        return resMax;
    }

    public void backTrack(char[] chars,int index,Set<Character> set){
        先动态更新 子序列最大长度
        if (set.size()>resMax){
            resMax=set.size();
        }
        0.终止条件
        if (index>= chars.length) return;

        1.选择列表
        for (int i = 0; i < chars.length; i++) {
            1.做选择,只有当前元素不在set里时,才进行回溯
            if (set.add(chars[i])){
                2.回溯
                backTrack(chars, index+1, set);
                3.撤销选择
                set.remove(chars[i]);
            
           当前元素,已存在于set里时,直接剪枝
            }else
                return;
        }
    }
}

6.1143. 最长公共子序列

在这里插入图片描述
在这里插入图片描述

1.解题思路(动态规划)

  • 1.建立二维动态数组dp,存储相同字符的个数
class Solution {
    public int longestCommonSubsequence(String text1, String text2) {
        int t1Len=text1.length();
        int t2Len=text2.length();
        1.建立二维动态数组,dp[i][j]存储字符串text1前i个元素,与,字符串text2前j个元素,公共的字符个数;
        int[][] dp = new int[t1Len+1][t2Len+1];
		2.双层for循环遍历
        for (int i = 0; i < t1Len; i++) {
            for (int j = 0; j < t2Len; j++) {
            	1.该位置,存在相同的字符时
                if (text1.charAt(i)==text2.charAt(j)){
                    dp[i+1][j+1] = dp[i][j]+1; 
                2.该位置,字符不同时,取左、上2个位置中较大的1}else {
                    dp[i+1][j+1] = Math.max(dp[i+1][j],dp[i][j+1]);
                }
            }
        }
        return dp[t1Len][t2Len];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于力扣刷C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简单的函数对象。在力扣刷中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷中,使用 string 可以方便地处理字符串相关的问。 9. 注意边界条件:在力扣刷中,边界条件往往是解决问的关键。需要仔细分析目,考虑各种边界情况,避免出现错误。 10. 注意时间复杂度:在力扣刷中,时间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法的时间复杂度,并尽可能优化代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值