检查a出现最多1次 连续l 3次不奖励
char[] a = s.toCharArray();
int count1 = 0, count2 = 0;
for (int i = 0; i < a.length; i++) {
if ('A' == a[i])
count1++;
}
for (int j = 0; j < a.length - 2; j++) {
if ('L' == a[j] && 'L' == a[j + 1] && 'L' == a[j + 2])
count2++;
}
if (count1 > 1 || count2 > 0)
return false;
return true;
- Isomorphic Strings
//如果是同构的输出正确 即重复的字符在另外一个字符串中也有重复的结构
class Solution {
public boolean isIsomorphic(String s, String t) {
//256个ASCII 放在一起节省空间
int[] sum = new int[512];
for(int i = 0;i<s.length();i++) {
//根据存放的位置 如果上个字符串有重复的会在原来的位置有数据存储如果比照不对会返回false
if(sum[s.charAt(i)]!=sum[t.charAt(i)+256]) return false;
//如果使用i的话因为初始i为0所以aa ab应该返回false却返回true 如果固定的值的话重复的数值无法判断
sum[s.charAt(i)] = sum[t.charAt(i)+256]=i+1;
}
return true;
}
}
- 1-bit and 2-bit Characters
//判断最后一个数是不是单比特
class Solution {
public boolean isOneBitCharacter(int[] bits) {
int j =0;
//判断尾数之前的数能否自成体系
while(j<bits.length-1){
//因为由0和1组成所以当bits[j]为0的时候只需要1个位置当为1的时候需要2个位置来满足条件
j += bits[j]+1;
}
if(j==bits.length-1) return true;
return false;
}
}
//贪心算法 在倒数第二往前找0作为终点因为如果是0的话那么之前的数必定满足条件只需要关心0之后的总个数能否被2整除 如果可以便满足条件
class Solution {
public boolean isOneBitCharacter(int[] bits) {
int i = bits.length - 2;
while (i >= 0 && bits[i] > 0) i--;
return (bits.length-i) % 2 == 0;
}
}
- Guess Number Higher or Lower
//猜大小 给定数范围查找数
//二分查找法
public class Solution extends GuessGame {
public int guessNumber(int n) {
int low = 1,high = n;
if(n==1) return 1;
//因为可能数会相等所以用<=不然有些数无法找到
while(low <= high){
//如果使用high+low会导致越界
int mid = low+(high-low)/2;
int res = guess(mid);
if(res==1) low = mid+1;
if(res == 0) return mid;
if(res == -1) high =mid-1;
}
return -1;
}
}
//三分查找
public class Solution extends GuessGame {
public int guessNumber(int n) {
int low = 1,high = n;
while(low <= high){
int mid1 = low+(high-low)/3;
int mid2 = high-(high-low)/3;
int res1 = guess(mid1);
int res2 = guess(mid2);
if(res1==0) return mid1;
if(res2==0) return mid2;
//因为在同个判断序列中所以要加else if 如果直接else的话会出错
else if(res1<0) high = mid1-1;
else if(res2>0) low = mid2+1;
else{
high = mid2-1;
low = mid1+1;
}
}
return -1;
}
}
因为在最坏的情况下 二分查找T(n)=1+2log2(n) 三分查找T(n)=1+4log3(n) 所以一般用二分
二分查找和三分查找的分析
26. Remove Duplicates from Sorted Array
//在一个排列号的数组中去重并返回独立的数的个数(只要返回的个数不重复即可)
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = 1; j < nums.length; j++) {
//给i序列每个安排独立
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
}
- Longest Substring Without Repeating Characters
//遍历字符找出最长的没有重复的字符 返回找出的字符长度
//下面这个超出了时间限制 brute force 暴力算法
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for(int i = 0;i<n;i++)
for(int j =i+1;j <= n;j++){
if(unique(s,i,j)) ans = Math.max(ans,j-i);
}
return ans;
}
public boolean unique(String s,int start,int end){
Set<Character> set = new HashSet<>();
for(int i = start;i<end;i++){
Character ch = s.charAt(i);
if(set.contains(ch)) return false;
set.add(ch);
}
return true;
}
}
//使用Set的特性即只能有一个不能重复减少时间复杂度
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0,i = 0,j = 0;
while(i<n &&j<n){
if(!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans,j-i);
}else{
set.remove(s.charAt(i++));
}
}
return ans;
}
}
//使用hashmap的key-value特性当遇到重复的时候可以直接到下一个字符位置减少时间复杂度
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Map<Character,Integer> map = new HashMap<>();
int ans = 0;
for(int i = 0,j = 0;j<n;j++){
//如果有重复就改变i的位置
if(map.containsKey(s.charAt(j)))
i = Math.max(i,map.get(s.charAt(j)));
//因为还有个本身所以+1
ans = Math.max(ans,j-i+1);
//保留最远距离的j+1作为新的起点
map.put(s.charAt(j),j+1);
}
return ans;
}
}
//因为已知只有128个ASCII码从中选字符所以直接new一个sum数组 减少空间复杂度提升减少运行时间
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int[] sum = new int[128];
int ans = 0;
for(int i = 0,j = 0;j<n;j++){
//因为下一个字符还没有在自己的位置有数值或者小于i且默认为0,所以可以进行j增加i不增加
i = Math.max(sum[s.charAt(j)],i);
ans = Math.max(ans,j-i+1);
//作为一个标记
sum[s.charAt(j)]=j+1;
}
return ans;
}
}
- Single Number
//找出整数数组中仅出现一次的数,其他的出现2次
//因为相同的数异或为0 而另外的数与0异或保持原样 所以可以找出仅出现一次的数
class Solution {
public int singleNumber(int[] nums) {
int a = 0;
for(int i = 0 ;i < nums.length;i++)
a ^=nums[i];
return a;
}
}
//放到set中遍历
class Solution {
public int singleNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for(int i = 0 ;i < nums.length;i++){
if(set.contains(nums[i])) set.remove(nums[i]);
else set.add(nums[i]);
}
//先转换成数组然后提取 或者用new个迭代器遍历next()
return (int)set.toArray()[0];
}
}
//另外用数学算法 2(a+b+c)-(a+a+b+b+c)=c 就使用每个数的两倍减去原来的总数得到那个单个