按奇偶排序数组
给你一个整数数组 nums,将 nums 中的的所有偶数元素移动到数组的前面,后跟所有奇数元素。
返回满足此条件的 任一数组 作为答案。
第一反应就是只需要将偶数都放在左边,奇数都放在右边,可以采用两个指针,一个在最左边,一个在最右边,同时向中间移动,需要判断left元素是不是偶数,如果是奇数,并且right元素是偶数就交换位置,但是如果left元素是偶数,那么left自增就可以,但是如果right元素是奇数,满足,right自减少。
public int[] sortArrayByParity(int[] nums) {
int left =0;
int right = nums.length -1;
while(left<right){
if(left<right && nums[left] % 2==0){
left++;
}
if(left<right && nums[right]%2!=0){
right--;
}
if(nums[left] %2!=0 && nums[right] %2==0 ){
int temp = nums[left];
nums[left] = nums[right];
nums[right]=temp;
left++;
right--;
}
}
return nums;
}
时间复杂度:O(n)
空间复杂度:O(1)
轮转数组
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
第一个想法是将数组一个一个进行反转,将最后的元素依次插到最前面。但是这个情况优点复杂,考虑的东西比较多。于是采用反转,先将所有元素反转,然后将k元素之前的元素再反转,k后面的元素也反转。这里需要将k转换成下标,也就是k-1位置的元素。
public void rotate(int[] nums, int k) {
k = k% nums.length;
reverse(nums,0,nums.length-1);
reverse(nums,0,k-1);
reverse(nums,k,nums.length-1);
}
public void reverse(int [] nums,int start,int end){
while(start <end){
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start+=1;
end-=1;
}
}
时间复杂度:O(N)第一次反转是O(N),第二次是O(k),第三次是O(N-k)
空间复杂度:O(1)
汇总区间
给定一个 无重复元素 的 有序 整数数组 nums 。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
“a->b” ,如果 a != b
“a” ,如果 a == b
先让快指针一直走,当快指针后面元素和当前元素不连续的时候,返回开始元素和快指针元素的字符串,然后这时候的慢指针就要跳转到快指针的后一个元素位置,作为下一次的初始位置。中间需要判断当前快慢指针是否在同一个位置,如果在,表示只有一个元素。
public List<String> summaryRanges(int[] nums) {
int slow = 0;
List<String> list = new ArrayList<>();
for(int fast =0;fast<nums.length;fast++){
//fast 向后遍历,不满足条件nums[fast]+1=nums[fast+1],就是不连续的
if(fast+1 ==nums.length || nums[fast] +1 !=nums[fast+1]){
StringBuilder sb = new StringBuilder();
// 记录下开始元素
sb.append(nums[slow]);
if(slow!=fast){
// 记录结束元素
sb.append("->").append(nums[fast]);
}
list.add(sb.toString());
// 下一个区间起始位置
slow =fast+1;
}
}
return list;
}
时间复杂度:O(N)
空间复杂度:O(1)
力扣 163,需要会员。
大体上和3.1一样,不过现在是获取缺失的空间
例如: nums[0,1,3,50,75] ,lower=0,upper=99
结果是: [“2”, “4->49”, “51->74”, “76->99”]
首先这一题一样采用,让快指针移动直到不连续,但是现在不需要慢指针了,只需要记录这个快指针元素和下一个位置元素的之间的空间输出即可,不过需要判断当前的元素是否超过lower和upper的范围。
public static List<String> findNonContiguousSpaces(int[] nums, int lower, int upper) {
List<String> list = new ArrayList<>();
int n = nums.length;
if (nums[0] > lower) {
int start = lower;
int end = nums[0] - 1;
list.add(start + "->" + end);
}
for (int fast = 1; fast < n - 1; fast++) {
int prev = nums[fast] + 1;
int cur = nums[fast + 1] - 1;
list.add(prev + "->" + cur);
}
if (nums[n - 1] < upper) {
int end = upper;
int start = nums[n - 1] - 1;
list.add(start + "->" + end);
}
return list;
}
时间复杂度:O(n)
空间复杂度:O(1)
替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
新建一个String,将字符串使用char保存里面每一个字符,如果这个字符为空的话,就拼接"%20",如果不是就直接拼接。
public String replaceSpace(String s) {
String rep = "";
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(c == ' '){
rep+="%20";
}else{
rep+=c;
}
}
return rep;
}
时间复杂度:O(N^2)主要是遍历字符串和再次拼接字符串。
很显然,时间空间效率比较低。
首先先计算出有多少个空格,添加一个%20,占用三个字节,而一个空格占用一个字节,所有最后多出来的长度就是2个字节,总共多出来2*n个字节,然后将stringbuffer的长度扩大,将慢指针放在新的字符串最后,快指针放在原字符串最后,当快指针遇到空格的时候,这时候需要使用三个字符替代一个空格,然后slow移动三个位置,而fast移动一个位置,直到fast到达开始位置。
public String replaceSpace(String s) {
StringBuffer str= new StringBuffer(s);
if(str ==null) return null;
int blankCount =0;
int len = str.length();
for(int i=0;i<len;i++){
if(str.charAt(i) == ' '){
blankCount++;
}
}
int newLength = len+2*blankCount;
str.setLength(newLength);
int slow = newLength-1;
int fast = len-1;
while(fast>=0 && slow!=fast){
char c = str.charAt(fast);
if(c==' '){
fast--;
str.setCharAt(slow--,'0');
str.setCharAt(slow--,'2');
str.setCharAt(slow--,'%');
}else{
str.setCharAt(slow,c);
fast--;
slow--;
}
}
return str.toString();
}