Day5 - 哈希表、字符串

18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abc 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

示例 1:

输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        //定义结果集
        List<List<Integer>> result = new ArrayList<>(); 
        //先排序数组
        Arrays.sort(nums);
        for(int i = 0; i < nums.length; i++){
             //对nums[i]剪枝
            if(nums[i]>0 && target>0 && nums[i]>target) break;
            //对nums[i]去重
            if(i>0 && nums[i-1]==nums[i]) continue;

            for(int j = i+1; j < nums.length; j++){
               
                //对nums[j]剪枝
                if( nums[i] + nums[j]>target && target>0) break;
                //对nums[j]去重
                if(j>i+1 && nums[j-1]==nums[j]) continue;
                //双指针法
                int left = j + 1;
                int right = nums.length - 1;
                
                while(left < right){
                    //防止溢出异常
                    long total = (long) nums[i] + nums[j] + nums[left] + nums[right];
                    if(total < target){
                        left++;
                    } else if(total > target){
                        right--;
                    } else{
                        result.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));

                        while(left < right && nums[left]==nums[left+1])   left++;
                        while(left < right && nums[right]==nums[right-1]) right--;
                      

                        left++;
                        right--;
                    }
                }
            }
        }
        return result;
    }
}

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"
class Solution {
    public void reverseString(char[] s) {
        int i = 0;
        int j = s.length - 1;
        while(i<j){
            //定义临时变量
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
            i++;
            j--;
        }
    }
}

 541. 反转字符串II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例 1:

输入:s = "abcdefg", k = 2
输出:"bacdfeg"
class Solution {
    public String reverseStr(String s, int k) {
        char ch[] = s.toCharArray();  //将字符串转换成数组
        
        for(int i = 0; i < ch.length; i+= 2*k){
            int left = i;
            //确定要反转的位置
            int right = Math.min(ch.length - 1,left + k - 1);
            while(left < right){
                 char temp = ch[left];
                ch[left] = ch[right];
                ch[right] = temp;
                left++;
                right--;
            }
        }
        return new String(ch);
    }
}

28.找出字符串中第一个匹配的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
class Solution {
    public int strStr(String haystack, String needle) {
        int next[] = new int[needle.length()];
        getNext(next,needle);
        int j = 0;
        for(int i = 0; i < haystack.length(); i++ ){
            while(j > 0 && haystack.charAt(i) != needle.charAt(j)) j = next[j-1];
            if(haystack.charAt(i) == needle.charAt(j)) j++;
            if(j == needle.length())
                return i-needle.length()+1;
        }
        return -1;
    }

    //基于前缀表(不减1)
    public void getNext(int[] next, String s){
        int j = 0;//前缀末尾
        next[0] = 0;
        for(int i = 1; i < s.length();i++){
            while(j >0 && s.charAt(j) != s.charAt(i))  j =next[j-1];
            if(s.charAt(j) == s.charAt(i)) j++;
            next[i] = j;
        }
    }
}

459.重复的子字符串 

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        /**
        思路:KMP算法
        1.初始化
        2.构造next数组
        3.判断子串构成
         */
         //1.初始化
        char[] chars = s.toCharArray();
        int[] next = new int[s.length()];
        int j = 0;
        int len = s.length();
        int count = 0;
        //2.构造next数组
        for(int i =1; i < s.length(); i++){
            while(j >0 && s.charAt(i) != s.charAt(j)) j = next[j-1];
            if(s.charAt(i) == s.charAt(j)) j++;
            next[i]  =j;
        }
        
        //2.构造next数组
        if(next[len-1] >0 && len % (len-next[len-1])== 0){
            return true;
        }
        return false;
    }
}

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值