//双指针法funremoveElement(nums: IntArray, `val`: Int): Int {if(nums.isEmpty())return-1var slow =0for(fast in nums.indices){if(nums[fast]!= `val`){
nums[slow]= nums[fast]
slow++}}//[0-slow]即为符合预期的数组元素return slow
}//双重for循环暴力破解//发现相等的直接往前移动填满funremoveElement2(nums: IntArray, `val`: Int): Int {var size = nums.size
var index =0while(index < size){if(nums[index]== `val`){//暴力填充数组for(indexInner in index until nums.size){
nums[indexInner -1]= nums[indexInner]}//此时下标i以后的数值向前移动了一位,所以i也向前移动一位
index--//此时数组的大小-1
size--}
index++}return index
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
977.有序数组的平方(easy)
描述
有序数组,平方之后也按顺序排序,不开辟新的空间
核心要点
平方之后,最大值分部在两头,这样就可以使用快慢指针来交换排序
代码
funsortedSquares(nums: IntArray): IntArray {var left =0var right = nums.size -1var result =IntArray(nums.size)var index = nums.size -1while(left <= right){if(nums[left]* nums[left]> nums[right]* nums[right]){
result[index--]= nums[left]* nums[left]
left++}else{
result[index--]= nums[right]* nums[right]
right--}}return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
209.(滑动窗口)长度最小的子数组(mid)
描述
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0,如: 输入:s = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。
//暴力法funminSubArrayLen0(target: Int, nums: IntArray): Int {var sum =0//子序列长度var subLength =0//每次比较之后的最终长度var result = Int.MAX_VALUE
for(i in nums.indices){//每次sum = 0 重新累加
sum =0for(j in i until nums.size){
sum += nums[j]if(sum >= target){//记录此时的长度
subLength = j - i +1//对比之前的长度
result =if(result < subLength)return result else subLength
//符合条件跳出循环break}}}returnif(result == Int.MAX_VALUE)0else result
}//滑动窗口funminSubArrayLen(target: Int, nums: IntArray): Int {var sum =0var subLength =0var result = Int.MAX_VALUE
//滑动窗口起始位置var left =0for(right in nums.indices){//开始累加
sum += nums[right]//滑动窗口while(sum >= target){
subLength = right - left +1
result =if(result < subLength) result else subLength
//移动窗口左边界
sum-=nums[left++]}}returnif(result == Int.MAX_VALUE)0else result
}
//典型的双指针funreverseString(s: CharArray): Unit {if(s.isEmpty())returnvar left =0var right = s.size -1while(left < right){//交换var temp = s[left]
s[left]= s[right]
s[right]= temp
left++
right--}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
541. 反转字符串II
描述
给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。 如果剩余字符少于 k 个,则将剩余字符全部反转。 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。 示例: 输入: s = “abcdefg”, k = 2 输出: “bacdfeg”
要点分析
只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
代码
funreverseStr(s: String, k: Int): String {val chars = s.toCharArray()var index =0while(index < chars.size){var left = index
//这里是判断尾数够不够k个来取决end指针的位置var right = Math.min(chars.size -1, left + k -1)while(left < right){val temp = chars[left]
chars[left]= chars[right]
chars[right]= temp
//移动
left++
right--}
index +=2* k
}return chars.toString()}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
剑指offer05 替换空格
描述
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 示例 1: 输入:s = “We are happy.” 输出:“We%20are%20happy.”
要点分析:
不开辟新的空间,统计空格,扩充数组空间
双指针技巧
代码
class Solution {public:
string replaceSpace(string s){
int count =0;// 统计空格的个数
int sOldSize = s.size();for(int i =0; i < s.size(); i++){if(s[i]==' '){
count++;}}// 扩充字符串s的大小,也就是每个空格替换成"%20"之后的大小
s.resize(s.size()+ count *2);
int sNewSize = s.size();// 从后先前将空格替换为"%20"for(int i = sNewSize -1, j = sOldSize -1; j < i; i--, j--){if(s[j]!=' '){
s[i]= s[j];}else{
s[i]='0';
s[i -1]='2';
s[i -2]='%';
i -=2;}}return s;}}
//字母匹配funcanConstruct(ransomNote: String, magazine: String): Boolean {if(ransomNote.isEmpty()|| magazine.isEmpty())returnfalse//26个字符var records =IntArray(26)//用magazine 添加for(charMagazine in magazine){
records[charMagazine-'a']+=1}//用信封消除for(charRansomeNote in ransomNote){
records[charRansomeNote-'a']-=1}//如果数组中存在负数则表示不匹配的for(record in records){if(record <0)returnfalse}returntrue}