3、
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
思想:
暴力法:遍历所有子字符串,找出最长的无重复字符的子字符串,复杂度为O(n^3);
优化:使用滑动窗口,使用一个HashMap存储字符以及其位置索引,使用双指针i=0,j=0,往前遍历j++,入到map中已经存储的字符,将i的值变为当前i与重复字符所在索引的最大值,及Math.max(man.get(s.charAt(j)),i);
代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
int i=0,j=0,ans=0;
Map<Character,Integer> map=new HashMap<>();
for(i=0,j=0;j<s.length();j++){
if(map.containsKey(s.charAt(j))){
i=Math.max(map.get(s.charAt(j)),i);
}
ans=Math.max(ans,j-i+1);
map.put(s.charAt(j),j+1);
}
return ans;
}
}
4、给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0
示例 2:
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5
思想:时间复杂度为log的一般是二分法,本题求中位数,所以没必要将整个数组进行排序,对于长度n,m的数组,k=(n+m+1)/2,只需要求第K小的数即可,然后分别对两个数组比较前k/2个数,若第一个数组的k/2位置比第二个数组小,则第一个数组的前k/2个数肯定都比中位数小,直接排除,从第一个数组的k/2+1位置开始重新比较,此时k=k-k/2。
代码:
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1=nums1.length,len2=nums2.length;
int left=(len1+len2+1)/2;
int right=(len1+len2+2)/2;
return (getKth(nums1,0,len1-1,nums2,0,len2-1,left)+getKth(nums1,0,len1-1,nums2,0,len2-1,right))*0.5;
}
public int getKth(int[] nums1,int start1,int end1,int[] nums2,int start2,int end2,int k){
int len1=end1-start1+1;
int len2=end2-start2+1;
if(len1>len2) return getKth(nums2,start2,end2,nums1,start1,end1,k);
if(len1==0) return nums2[start2+k-1];
if(k==1) return Math.min(nums1[start1],nums2[start2]);
int i=start1+Math.min(len1,k/2)-1;
int j=start2+Math.min(len2,k/2)-1;
if(nums1[i]>nums2[j])
return getKth(nums1,start1,end1,nums2,j+1,end2,k-(j-start2+1));
else
return getKth(nums1,i+1,end1,nums2,start2,end2,k-(i-start1+1));
}
}
5、最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
思想:利用回文串的对称性,对每个字符求其回文串。求回文串长度的函数为一字符为中心向两边扩展,到达最大长度时记录长度length,此回文子串的起始位置为i-(length-1)/2.(i为中心字符的下标索引),最终位置为i+length/2。
代码:
class Solution {
public String longestPalindrome(String s) {
if(s==null||s.length()<1) return "";
int start=0,end=0;
for(int i=0;i<s.length();i++){
int len1=ishw(s,i,i);
int len2=ishw(s,i,i+1);
int len=Math.max(len1,len2);
if(len>end-start){
start=i-(len-1)/2;//
end=i+len/2;
}
}
return s.substring(start,end+1);
}
public int ishw(String s,int left,int right ){
int l=left,r=right;
while(l>=0&&r<s.length()&&s.charAt(l)==s.charAt(r)){
l--;//最后l可能为-1
r++;
}
return r-l-1;
}
}
另一种算法:
利用最长公共子串求解,先反转字符串,然后求解两个字符串的最长公共子串,然后判断这第二个子串是否正好对应的是第一个子串。利用关系式:最后匹配的字符索引为j,此时匹配的字符串长度为length1,字符串最大长队为length,对应第一个子字符串的结束位置为i,有关系:
j+length-1+length1-1=i.
代码:
class Solution {
public String longestPalindrome(String s) {
if(s.equals("")) return "";
int len=s.length();
String reverse=new StringBuffer(s).reverse().toString();
int maxlen=0,maxend=0;
int[] arr=new int[len];
for(int i=0;i<len;i++){
for(int j=len-1;j>=0;j--){
if(s.charAt(i)==reverse.charAt(j)){//判断公共子字符串
if(i==0||j==0) arr[j]=1;
else arr[j]=arr[j-1]+1;
}
else arr[j]=0;
if(arr[j]>maxlen){
int before=len-j-1;
if(before+arr[j]-1==i){//判断是否为回文串
maxlen=arr[j];
maxend=i;
}
}
}
}
return s.substring(maxend-maxlen+1,maxend+1);
}
}
6、 Z字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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
思想:刚开始考虑二维数组,后来发现输出的时候是按行输出,并不需要管这一行的任意一个字符是在哪一列,只需要按行输出就行。所有使用一个有numRows个元素的String数组或者List。加一个判断是向下走还是向上走的boolean类型变量,
以及序列数row,代码:
class Solution {
public String convert(String s, int numRows) {
if(numRows==1){//特殊情况先进行判断
return s;
}
int len=Math.min(numRows,s.length());//可能字符串的长度小于numRows
int row=0;
boolean boo=false;
String[] rows=new String[len];
for(int m=0;m<len;m++){//先初始化每一个String
rows[m]="";
}
for(int j=0;j<s.length();j++){
rows[row] += s.substring(j,j+1);
if(row==0||row==numRows-1){//判断是否到达最上边或者最下边
boo=!boo;
}
row+=boo? 1:-1;
}
String ans="";
for(int i=0;i<len;i++){
ans+=rows[i];
}
return ans;
}
}
7、整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
思想:很简单的一道题,我选择转换为字符串后反转,再转回int,但第一次没注意越界问题,出现了异常:Line 13: java.lang.NumberFormatException: For input string: “9646324351”,后来把代码块放在了try catch语句中 抛出0就行了
代码:
class Solution {
public int reverse(int x) {
boolean isA=true;
if(x<0){
x=-x;
isA=false;
}
Integer x1=x;
String s=x1.toString();
StringBuffer s1=new StringBuffer(s);
s1.reverse();
String s2=s1.toString();
try{
Integer x2= new Integer(s2);//如果不捕获异常,会有越界问题
if(!isA){
return -x2;
}
return x2;
}
catch(Exception e){
return 0;
}
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。