Leetcode面T1(1-9)字符

Q1.1 判定字符是否唯一

实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
示例 1:
输入: s = “leetcode”
输出: false
示例 2:
输入: s = “abc”
输出: true

限制:
0 <= len(s) <= 100
如果你不使用额外的数据结构,会很加分。

方法一、双循环牺牲时间

不使用额外的数据结构,所以计数的方法不能用。

这种情况来说,容易想到的就是牺牲时间换空间,第一种方法就是用双循环来代替额外的数据结构。

内外循环都遍历整个字符串,然后对比是否除了自身之外还有别的位置是一样的字符。

class Solution {
    public boolean isUnique(String astr) {
        if(astr.length()==0||astr.length()==1){
            return true;
        }
        for(int i=0;i<astr.length();i++){
            for(int j=0;j<astr.length()&&j!=i;j++){
                if(astr.charAt(i)==astr.charAt(j)){
                    return false;
                }
            }
        }
        return true;
    }
}

方法二:

public boolean isUniqueChars2(String str)
{
    //ascii码表总共就256个字符,如果长度大于256就直接回false
    if (str.length() > 256) return false;
     
    //一个个字符取过去,每取一个就比较一次,若之前没有过,则将该位值置为true.
    boolean[] char_Set = new boolean[256];
    for (int i = 0; i < str.length; i++)
    {
        int val = str.chatAt(i);
        if (char_Set[val])
        {
            return false;
        }
        char_Set[val] = true;
    }
}

Q1.2 判定是否互为字符重排

题目:给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:

输入: s1 = "abc", s2 = "bca"
输出: true 
示例 2:

输入: s1 = "abc", s2 = "bad"
输出: false
说明:

0 <= len(s1) <= 100
0 <= len(s2) <= 100

/*
 *此处定义数组长度为128,因为基础ASCII码是128位,如果算上拓展ASCII码才有256位。
 *思路:其实就是计算 两个字符串 中是否包含一样多的相同字符
 */
 
class Solution {
 
    public boolean CheckPermutation(String s1, String s2) {
      if (s1.length() != s2.length()) {
        return false;
      }
      int[] repeats1 = new int[128];
 
      for (int i = 0; i < s1.length(); i++) {
        repeats1[s1.charAt(i)]++;
        repeats1[s2.charAt(i)]--;
      }
 
      for (int i = 0; i < repeats1.length; i++) {
        if (repeats1[i] != 0) {
          return false;
        }
      }
      return true;
    }
}

Q1.3 URL化

URL化。编写一种方法,将字符串中的空格全部替换为%20。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。(注:用Java实现的话,请使用字符数组实现,以便直接在数组上操作。)

示例1:

 输入:"Mr John Smith    ", 13
 输出:"Mr%20John%20Smith"

思路

注意:这里只说知道字符串“真实”长度,但S.length()足够存放新增字符,可能后面还有好多空格。

计算符串“真实”长度空格数,然后从后往前reset字符串,最后去除后面的空格

class Solution {
public:
    string replaceSpaces(string S, int length) {
        int space=0;//count the space num
        for(int i=0;i<length;i++){
            if(S[i]==' ') space++;
        }
        int j=length+2*space-1;
        for(int i=length-1;i>=0;i--){
            if(S[i]==' '){
                S[j--] = '0';
                S[j--] = '2';
                S[j--] = '%';
            }
            else S[j--] = S[i];
        }
        return S.substr(0,length+2*space);//cut the string, don't let space influence the result
    }
};

Q1.4 回文排列

给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。
回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。
回文串不一定是字典当中的单词。

示例1:

输入:“tactcoa”

输出:true(排列有"tacocat"、“atcocta”,等等)

网上大佬的代码

var canPermutePalindrome = function (s) {
    let mySet = new Set();
    for (let i of s) {
        mySet.has(i) ? mySet.delete(i) : mySet.add(i)
    }
    return mySet.size <= 1
};

优化后的(减少了时间)

var canPermutePalindrome = function (s) {
    let hash = [];
    for (let i of s) {
        hash[i] = 0;
    }
    for (let i of s) {
        hash[i]++
    }
    let count = 0;
    for (let j of Object.values(hash)) {
        if (j % 2 != 0) {
            count++
        }
    }
    return count < 2 ? true : false;
};

Q1.5 一次编辑

字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。

示例 1:

输入:
first = “pale”
second = “ple”
输出: True

示例 2:

输入:
first = “pales”
second = “pal”
输出: False

思路:
1.如果两个字符串长度差大于1,则输出false
2.如果两个字符串长度相等,则两个字符串同一个下标的字符不同的个数应小于2个。
3.如果两个字符串长度差等于1,则长度长的字符串必须包含所有长度短的字符串的每个字符,如果有一个字符没有,则输出false
4,。如果长度长的字符串包含所有长度短的字符串的每个字符,则继续判断,将长度长的字符串多出的字母除去,再判断两个字符串的hashcode是否相等,不等则false

package s;
public class onceEdit {
	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		String str1="palesdasdads";
		String str2="plesdasdas";
		boolean res = ifOnceEdit(str1,str2);
		long endTime = System.currentTimeMillis();//获取当前时间
		System.out.println(res);
		System.out.println("程序运行时间:"+(endTime-startTime)+"ms");
		
	}
	private static boolean ifOnceEdit(String str1, String str2) {
		if (Math.abs(str1.length()-str2.length())>=2) {
			return false;
		}
		else if (str1.length()==str2.length()){
			int count=0;
			for (int i=0;i<str1.length();i++) {
				if(str1.charAt(i)!=str2.charAt(i)) {
					count=count+1;
				}
			}
			if(count>=2) {
				return false;
			}
		}
		else{
			String str11=str1.length()>str2.length()?str1:str2;
			String str22=str1.length()>str2.length()?str2:str1;
			for(int i=0;i<str22.length();i++) {
				if(str11.charAt(i)!=str22.charAt(i)) {
					String str111 =str11.substring(i+1);
					String str222=str22.substring(i);
					if(str11.substring(i+1).equals(str222)) {
						return true;
					}
					
				}
			}
		}	
	
		return false;
}}

Q1.6 字符串压缩

字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。

示例1:

 输入:"aabcccccaaa"
 输出:"a2b1c5a3"
示例2:

 输入:"abbccd"
 输出:"abbccd"
 解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。

class Solution {
    public String compressString(String S) {  
		if (S == null || S.length() <= 2) {//首先判断字符串是否为空,是否长度小于2,是直接返回
			return(S);
        }
        //注意StringBuilder不能写在if判断前面
        StringBuilder a = new StringBuilder().append(S.charAt(0));
		int num = 1;
	        for(int i=1;i < S.length();i++){     
	            char c = S.charAt(i-1);
	            char b = S.charAt(i);
	            if( c == b){
	                num++;
	            }else{
	             a.append(num).append(S.charAt(i));
	               num = 1;               
	            } 
	        }
            //最后判断输出结果与原字符串长度是否小于他
	        return(a.append(num).length() < S.length() ? a.toString():S);
    }
}

Q1.7 旋转矩阵

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?

 

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

class Solution {
    // 正方形
    public void rotate(int[][] matrix) {
        int[][] res = new int[matrix.length][matrix.length];
        for (int i = 0; i < matrix.length; i++) {
            int temp[] = new int[matrix.length];
            for (int j = matrix.length - 1; j >= 0 ; j--) {
                temp[matrix.length - j - 1] = matrix[j][i];
            }
            res[i] = temp;
            
        }
        for (int i = 0; i < res.length; i++) {
            matrix[i] = res[i];
        }
        // matrix = res; 这个没有用
    }
}

Q1.8 零矩阵

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

 

示例 1:

输入:
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出:
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]
示例 2:

输入:
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
输出:
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]

public void setZeros(int[][] matrix)
{
    boolean[] row = new boolean[matrix.length];
    boolean[] column = new boolean[matrix[0].length];
    
    //确认哪些行哪些列需要置0
    for(int i = 0; i < matrix.length; i++)
    {
        for(int j = 0; j < matrix[0].length; j++)
        {
            if (matrix[i][j] == 0)
            {
                row[i] = true;
                column[j] = true;
            }
        }
    }
    
    //置0
    for(int i = 0; i < matrix.length; i++)
    {
        for(int j = 0; j < matrix[0].length; j++)
        {
            if (row[i] || column[j])
            {
                matrix[i][j] = 0;
            }
        }
    }   
}

Q1.9 字符串轮转

字符串轮转。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

示例1:

 输入:s1 = "waterbottle", s2 = "erbottlewat"
 输出:True
示例2:

 输入:s1 = "aa", s2 = "aba"
 输出:False

package com.yuhl.right.leetcode;

/**
 * @author yuhl
 * @Date 2020/10/25 8:33
 * @Classname IsFlipedString
 * @Description 字符串轮转
 * 字符串轮转。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。
 *
 * 示例1:
 *  输入:s1 = "waterbottle", s2 = "erbottlewat"
 *  输出:True
 *
 * 示例2:
 *  输入:s1 = "aa", s2 = "aba"
 *  输出:False
 * 提示:
 * 字符串长度在[0, 100000]范围内。
 * 说明:
 * 你能只调用一次检查子串的方法吗?
 */
public class IsFlipedString {
    public static void main(String[] args) {
        String s1 = "waterbottle";
        String s2 = "erbottlewat";
        boolean flipedString = isFlipedString(s1, s2);
        System.out.println(flipedString);
    }

    public static boolean isFlipedString(String s1, String s2) {
        //旋转的化,考虑s2+s2.contans(s1) 如果为true则为旋转,要不然不是旋转的,注意对长度的判断
        if(s1.length() != s2.length()) return false;
        if((s2+s2).contains(s1)){
            return true;
        }else{
            return false;
        }

    }
}

Q1.10 查找常用字符

给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次。

 

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

示例 1:
输入:[“bella”,“label”,“roller”]
输出:[“e”,“l”,“l”]

示例 2:
输入:[“cool”,“lock”,“cook”]
输出:[“c”,“o”]

提示:

1 <= A.length <= 100
1 <= A[i].length <= 100
A[i][j] 是小写字母

思路:把数组中的第一个元素但拿出来,然后把第一个元素的每个字符拿出来与其他元素的字符比较,如果相等,就标记该元素。如果除了第一个元素,其他所有的元素都被标记,则这个字符是常用字符。
还要把这个字符从元素中删除,避免再次比较。

public static List<String> commonChars(String[] s) {
         //定义并初始化两个数组arr和array
         int[] arr = new int[26];
         int[] array = new int[26];
         for(int i = 0;i<26;i++) {
             arr[i] = 100;
             array[i] = 0;
         }
         for(String str : s) {
             //初始化array
             for(int i = 0;i<26;i++) {
                 array[i] = 0;
             }
             //统计每个字符出现的次数
             for(int i = 0;i<str.length();i++) {
                 ++array[str.charAt(i) - 'a'];
             }
             //统计每个字符在当前字符串之前所有字符串出现的次数,以出现最少次数为标准赋值
             for(int i = 0;i<26;i++) {
                 arr[i] = Math.min(arr[i], array[i]);
             }
         }
         List<String> list = new ArrayList<String>();
         //遍历arr
         for(int i = 0;i<26;i++) {
             //j<arr[i]  判断每个字符出现个数,然后进行添加
             for(int j = 0;j<arr[i];j++) {
                 String ch = "";
                 ch+=(char)('a'+i);
                 list.add(ch);
             }
         }
         return list;
     }

参考:https://www.cnblogs.com/du001011/p/10508637.html

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值