目录
写在前面的小日记
给笔记本换了c面和电源。终于可以支持我流畅地按n键以及不插电使用电脑了。发生了小问题,用绝缘胶带固定损坏的机械硬盘排线的时候粘到了背面的原件导致开机失败,但是顺利解决,还好主板没坏,要不我直接“彻底疯狂”。
代码部分
题1576
难度简单99收藏分享切换为英文接收动态反馈
给你一个仅包含小写英文字母和
'?'
字符的字符串s
,请你将所有的'?'
转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。注意:你 不能 修改非
'?'
字符。题目测试用例保证 除
'?'
字符 之外,不存在连续重复的字符。在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。
自己的代码:
class Solution {
public String modifyString(String s) { //a:97
int len = s.length();
char[] S = s.toCharArray();
if(S[0] == '?')
{
if(len >1 && S[1] >= 97 && S[1] < 122) {S[0] = (char)(S[1]+1);}
else {S[0] = 97;}
}
for(int i = 1 ; i < len ; i ++)
{
if(S[i] != '?') {continue;}
else
{
int head = (int)S[i-1];
if(head == 122) {head = 96;}
if(i != len-1 && S[i+1] != head+1) {S[i] = (char)(head+1);}
else if(i == len-1) {S[i] = (char)(head+1);}
else if(i != len-1 && S[i+1] == head+1)
{
if(head == 121) {S[i] = 97;}
else {S[i] = (char)(head+2);}
}
}
}
String res = new String(S);
return res;
}
}
先判断掉特殊情况。先对第一个位置进行判断,使得第一个位置不是问号。从第二个位置开始,根据前一个位置的字符进行填写,填写内容为前一个字母+1(前一个为z则填入a)。
题26
难度简单2389收藏分享切换为英文接收动态反馈
给你一个有序数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); }
自己的代码:
class Solution {
public int removeDuplicates(int[] nums) {
int len = nums.length;
if(len == 0 || len == 1) {return len;}
//双指针法
int insert , search;
insert = 0;
for(search = 1 ; search < len ; search ++)
{
if(nums[search] == nums[search-1]) {continue;}
else
{
insert ++;
nums[insert] = nums[search];
}
}
return insert+1;
}
}
隐隐约约中从前打过这个题,在acm那边(只搞了很短一段时间)。先判断掉特殊情况。设置双指针,一个用于探测字符,一个用于定位插入位置。若探测字符与其前一个字符不相等,则将该字符放在插入位置上,并将插入位置向后挪一位;若相等,则continue掉,判断下一个字符。
题27
难度简单1137收藏分享切换为英文接收动态反馈
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 int len = removeElement(nums, val); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); }
自己的代码:
class Solution {
public int removeElement(int[] nums, int val) {
int len = nums.length;
if(len == 0) return 0;
if(len == 1 && nums[0] != val) return 1;
if(len == 1 && nums[0] == val) {nums = null; return 0;}
int search , insert = 0;
for(search = 0 ; search < len ; search ++)
{
if(nums[search] == val)
{
continue;
}
else
{
nums[insert] = nums[search];
insert ++;
}
}
return insert;
}
}
这题与26题本质上是相同的,不过不是与前一个字符比较,而是与val比较。
题5
难度中等4545收藏分享切换为英文接收动态反馈
给你一个字符串
s
,找到s
中最长的回文子串。
自己的代码:
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
if(len == 0 || len == 1) {return s;}
char[] S = s.toCharArray();
int position = 0 ,lenres = 1;
for(int i = 0 ; i < len ; i++)
{
if(len - i + 1 <= lenres)
{
String res = s.substring(position , position+lenres);
return res;
}
int left , right , right0;
left = i;
right0 = right = len;
while(left < right)
{
left = i;
right = right0-1;
while(left < right && S[left] != S[right]) {right --;}
right0 = right;
while(left < right && S[left] == S[right])
{
left ++;
right --;
}
if(S[left] == S[right])
{
if(right0 - i + 1 > lenres)
{
lenres = right0 - i + 1;
position = i;
}
}
else {continue;}
}
}
String res = s.substring(position , position+lenres);
return res;
}
}
转字符串,使用for循环,逐步缩短查找区域。对于一个查找区域,设置头为区域的头,尾为区域的尾,从尾向前寻找与头相同的字符,设置为新的尾,对于头尾同时向内探测,判断是否回文。若该段是回文,则将该段长度与保存的最长回文串长度比较,若超过则更新长度与回文串起始位置;若未超过则再次从探测前的尾向前寻找与头相同的字符,头归位,再次判断。在缩短查找区域时,判断新的查找区域是否短于保存的最长回文串长度,若短于,则不需继续进行,直接返回,若长于则继续判断。
java小知识部分
题1576
Unicode码中a~z的编号为97-122(61H-7AH)。A~Z的编号为65-90(41H-5AH)。0~9的编号为48-57(30H-39H)。
String转char[]用.toCharArray[];char[]转String用= new String(S);。
题27
再确定一下,String字符串求长是.length();int数组求长是length。
题5
在区域缩短的时候加入判断是否区域已经小于当前取得的最大长度值,这样可以缩短算法时间。
注意循环中变量的变化,判断哪些变量值需要回归,哪些不需要。