27. 移除元素https://leetcode-cn.com/problems/remove-element/
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
1、暴力法
每次检测到nums[i]==val 就从后往前移动一遍元素
//暴力解法 遍历
public int removeElement1(int[] nums,int val){
int length=nums.length;
for (int i= 0;i< length;++i){
if(nums[i]==val){
for (int j=i+1;j<length;++j){
nums[j-1]=nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
length--;// 此时数组的大小-1
}
}
return length;
}
2、双指针
使用两个指针 left right
left---------指向要插入的位置
right-------指向需要向前移动的元素
如果nums[right]!=val 就证明该元素需要向前移动
//双指针 快慢指针
//left慢指针 right快指针
public int removeElement(int[] nums,int val){
int n=nums.length;
int left=0;
for (int right=0;right<n;++right){
// 不等于目标值时 left才移动
//-------这里要用if处理不相等时的情况
if(nums[right]!=val){
nums[left]=nums[right];
left++;
}
}
return left;
}
// 时间复杂度:O(n)
// 空间复杂度:O(1)
344. 反转字符串https://leetcode-cn.com/problems/reverse-string/
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
使用两个指针 left和 right
进行首尾对称调换即可
//双指针
//分别指向开头和结尾
public void reverseString1(char[] s) {
int n=s.length;
//如果s的长度为偶数 循环结束时 right<left左边
//如果s的长度为奇数 循环结束时 right=left
for(int left=0,right=n-1;left<right;++left,--right){
char tmp=s[left];
s[left]=s[right];
s[right]=tmp;
}
}
剑指 Offer 05. 替换空格https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/
如果想把这道题目做到极致,就不要只用额外的辅助空间了!
首先扩充数组到每个空格替换成"%20"之后的大小。
然后从后向前替换空格,也就是双指针法,过程如下:
i指向新长度的末尾,j指向旧长度的末尾
//方法1-------变为char数组 扩充3倍 遍历即可
public String replaceSpace1(String s) {
int length=s.length();
char[] array=new char[length*3];
int size=0;
for(int i=0;i<length;++i){
char c=s.charAt(i);
if(c==' '){
array[size++] = '%';
array[size++] = '2';
array[size++] = '0';
}else {
array[size++] = c;
}
}
String newStr = new String(array, 0, size);
return newStr;
}
//方法2--------StringBuilder
//使用一个新的对象,复制 str,复制的过程对其判断,是空格则替换,否则直接复制,类似于数组复制
public static String replaceSpace2(StringBuffer str) {
if (str == null) {
return null;
}
//选用 StringBuilder 单线程使用,比较快,选不选都行
StringBuilder sb = new StringBuilder();
//使用 sb 逐个复制 str ,碰到空格则替换,否则直接复制
for (int i = 0; i < str.length(); i++) {
//str.charAt(i) 为 char 类型,为了比较需要将其转为和 " " 相同的字符串类型
//if (" ".equals(String.valueOf(str.charAt(i)))){
if (str.charAt(i) == ' ') {
sb.append("%20");
} else {
sb.append(str.charAt(i));
}
}
return sb.toString();
}
//方法3-----------------双指针--从后向前移动
//如果想把这道题目做到极致,就不要只用额外的辅助空间了!
public String replaceSpace(String s){
if(s==null||s.length()==0){
return s;
}
//扩充空间为空格数量的2倍
StringBuilder sb=new StringBuilder();
for(int i=0;i<s.length();++i){
if(s.charAt(i)==' '){
sb.append(" ");
}
}
//若是没有空格直接返回
if(sb.length()==0){
return s;
}
//有空格情况 定义两个指针
int left=s.length()-1;//左指针:指向原始字符串最后一个位置
s+=sb.toString();
int right=s.length()-1;//右指针:指向扩展字符串的最后一个位置
char[] chars=s.toCharArray();
while (left>=0){
if(chars[left]==' '){
chars[right--]='0';
chars[right--]='2';
chars[right--]='%';
}else {
chars[right--]=chars[left];
}
left--;
}
return new String(chars);
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。