力扣刷题—字符串

1.14. 最长公共前缀

最长公共前缀

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

  • 如果不存在公共前缀,返回空字符串 “”。
    力扣刷题—字符串_第1张图片

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 码表中的可打印字符。
    力扣刷题—字符串_第2张图片

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

  • 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
    力扣刷题—字符串_第3张图片

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. 无重复字符的最长【子串】

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

力扣刷题—字符串_第4张图片

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. 最长公共子序列

力扣刷题—字符串_第5张图片
力扣刷题—字符串_第6张图片

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];
    }
}

你可能感兴趣的:(力扣刷题思考,字符串,leetcode,算法)