leetcode3-7

3. 无重复字符的最长子串

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

解:双指针,两个指针内用hashset判重。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || "".equals(s) || s.isEmpty()) return 0;
        HashSet<Character> set = new HashSet<>();
        char[] arr = s.toCharArray();
        int length = 1;
        int i=0;int j=1;
        set.add(arr[0]);
        while(j<arr.length&&i<=j){
            if(!set.contains(arr[j])){
                set.add(arr[j]);
                length = Math.max(length,j-i+1);
                j++;
            }else{
                set.remove(arr[i]);
                i++;
            }
        }
        return length;
    }
}

4. 两个排序数组的中位数

给定两个大小为 m 和 n 的有序数组 nums1nums2

请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。

解:二分的思想,将此问题转化为两个排序数组求第K小的元素,其中K为(m+n)/2,首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int l1 = nums1.length;
        int l2 = nums2.length;
        if((l1+l2)%2==1){
            return find(nums1,0,l1,nums2,0,l2,(l1+l2)/2+1);
        }else{
            return (find(nums1,0,l1,nums2,0,l2,(l1+l2)/2+1)+find(nums1,0,l1,nums2,0,l2,(l1+l2)/2))/2;
        }
    }

    private double find(int[] nums1, int begin1,int end1,int[] nums2,int begin2,int end2,int k){
        //确保后一个数组长
        if(end1>end2){
            return find(nums2,begin2,end2,nums1,begin1,end1,k);
        }
        if(end1==0){
            return nums2[begin2+k-1];
        }
        if(k==1){
            return Math.min(nums1[begin1],nums2[begin2]);
        }
        int ma = Math.min(k/2,end1);
        int mb = k-ma;
        if(nums1[begin1+ma-1]>nums2[begin2+mb-1]){
            return find(nums1,begin1,end1,nums2,begin2+mb,end2-mb,k-mb);
        }else if(nums1[begin1+ma-1]<nums2[begin2+mb-1]){
            return find(nums1,begin1+ma,end1-ma,nums2,begin2,end2,k-ma);
        }else{
            return nums1[begin1+ma-1];
        }
    }
}

5. 最长回文子串

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

解:动态规划,dp[i][j]表示s[i..j]是否是回文串,dp[i][j]=0当且仅当dp[i+1][j-1]==1&&s[i]==s[j],记录当前最大的长度以及开始索引,从长度为3的子串开始遍历,最后返回全局最大的即可.

class Solution {
    public String longestPalindrome(String s) {
        if (s == null || s.length() <= 1) return s;
        int length = s.length();
        int dp[][] = new int[length][length];
        int max = 1;
        int start = 0;
        //初始情况,长度为1或者2时
        for (int i = 0; i < length; i++) {
            dp[i][i] = 1;
            if (i < length - 1 && s.charAt(i) == s.charAt(i + 1)) {
                dp[i][i + 1] = 1;
                max = 2;
                start = i;
            }
        }
        for(int len = 3;len<=length;len++){
            for(int i=0;i<length-len+1;i++){
                int j = i+len-1;
                if(s.charAt(i) == s.charAt(j) && dp[i+1][j-1] == 1){
                    dp[i][j] = 1;
                    if(len>max){
                        start = i;
                        max = len;
                    }
                }
            }
        }
        return s.substring(start, start + max);
    }
}

6. Z字形变换

将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数:

P   A   H   N
A P L S I I G
Y   I   R

解:找规律+操作题

class Solution {
    public String convert(String s, int numRows) {
        if (numRows == 1 || s == null || s.length() < 2||s.length()<numRows) return s;
        int step = 2 * (numRows - 1);
        StringBuilder sb = new StringBuilder();
        //第一行
        for (int i = 0; i * step < s.length(); i++) {
            sb.append(s.charAt(i * step));
        }
        //中间
        for (int i = 1; i < numRows - 1; i++) {
            sb.append(s.charAt(i));
            if(step-i<s.length()){
                sb.append(s.charAt(step - i));
            }
            for (int j = 1; j * step + i < s.length(); j++) {
                sb.append(s.charAt(j * step + i));
                if(j * step - i+step<s.length()){
                    sb.append(s.charAt(j * step - i+step));
                }
            }
        }
        //最后一行
        for (int i = 0; i * step + numRows - 1 < s.length(); i++) {
            sb.append(s.charAt(i * step + numRows - 1));
        }
        return sb.toString();
    }
}

7. 反转整数

给定一个 32 位有符号整数,将整数中的数字进行反转。

解:注意溢出

class Solution {
    public int reverse(int x) {
        boolean b=false;
        if(x<0){
            x=-x;
            b=true;
        }
        char[] chars = String.valueOf(x).toCharArray();
        int i=0,j=chars.length-1;
        char c;
        while(i<j){
            c=chars[i];
            chars[i]=chars[j];
            chars[j]=c;
            i++;
            j--;
        }
        int result = 0;
        try {
            result = Integer.parseInt(String.valueOf(chars));
        }catch (NumberFormatException e){
            return 0;
        }
        if(b){
            result=0-result;
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/lengyuedanhen/article/details/81836238
今日推荐