Leetcode_移除元素及其相关类似题目

26. 删除有序数组中的重复项

 public int removeDuplicates(int[] nums) {
    if(nums == null || nums.length == 0) return 0;
    int p = 0;
    int q = 1;
    while(q < nums.length){
        if(nums[p] != nums[q]){
            nums[p + 1] = nums[q];
            p++;
        }
        q++;
    }
    return p + 1;
}


学习大佬们的通用解法整理
推广到保留 k 个相同数字,对于前 k 个数字,我们可以直接保留。

class Solution {
    public int removeDuplicates(int[] nums) {   
        return process(nums, 1);
    }
    int process(int[] nums, int k) {
        int idx = 0; 
        for (int x : nums) {
            if (idx < k || nums[idx - k] != x) nums[idx++] = x;
        }
        return idx;
    }
}

80. 删除有序数组中的重复项 II

class Solution {
    public int removeDuplicates(int[] nums) {
        int index=0;
        for(int x :nums)
        {
            if(index<2||nums[index-2]!=x) nums[index++]=x;
        }
        return index;
    }
}

27. 移除元素

class Solution {
    public int removeElement(int[] nums, int val) {
        int low=0;
        for(int fast=0;fast<nums.length;fast++)
        {
            if(nums[fast]!=val)
            {
                nums[low++]=nums[fast];
            }
        }
        return low;
    }
}

通用解法

class Solution {
    public int removeElement(int[] nums, int val) {
        int index=0;
        for(int x :nums)
        {
            if(x!=val)  nums[index++]=x;
        }
        return index;
    }
}

283.移动零

初步想法

class Solution {
    public void moveZeroes(int[] nums) {
        int index=0;
        for(int x:nums)
        {
            if(x!=0)    nums[index++]=x;
        }
        for(int i=index;i<nums.length;i++)
            nums[i]=0;
    }
}

想法二 快排思想

class Solution {
	public void moveZeroes(int[] nums) {
		if(nums==null) {
			return;
		}
		int j = 0;
		for(int i=0;i<nums.length;i++) {
			//当前元素!=0,就把其交换到左边,等于0的交换到右边
			if(nums[i]!=0) {
				int tmp = nums[i];
				nums[i] = nums[j];
				nums[j++] = tmp;
			}
		}
	}
}	

844.比较含退格的字符串

使用栈

class Solution {
    public boolean backspaceCompare(String S, String T) {
        Stack<Character> s1=new Stack<>(),s2=new Stack<>();
        for (int i = 0; i <S.length() ; i++) {
            char c =S.charAt(i);
            if(c=='#'){
                if(!s1.empty())
                    s1.pop();
            }
            else {
                s1.push(c);
            }
        }
        for (int i = 0; i <T.length() ; i++) {
            char c =T.charAt(i);
            if(c=='#'){
                if(!s2.empty())
                    s2.pop();
            }
            else {
                s2.push(c);
            }
        }
        if(s1.size()!=s2.size()) return false;
        while (!s1.empty()){
            if(s1.pop()!=s2.pop()){
                return false;
            }
        }
        return true;
    }
}

或者直接用字符串来模拟栈

// 普通方法(使用栈的思路)
class Solution {
    public boolean backspaceCompare(String s, String t) {
        StringBuilder ssb = new StringBuilder(); // 模拟栈
        StringBuilder tsb = new StringBuilder(); // 模拟栈
        // 分别处理两个 String
        for (char c : s.toCharArray()) {
            if (c != '#') {
                ssb.append(c); // 模拟入栈
            } else if (ssb.length() > 0){ // 栈非空才能弹栈
                ssb.deleteCharAt(ssb.length() - 1); // 模拟弹栈
            }
        }
        for (char c : t.toCharArray()) {
            if (c != '#') {
                tsb.append(c); // 模拟入栈
            } else if (tsb.length() > 0){ // 栈非空才能弹栈
                tsb.deleteCharAt(tsb.length() - 1); // 模拟弹栈
            }
        }
        return ssb.toString().equals(tsb.toString());
    }
}

法三 学习到的双指针

class Solution {
    public boolean backspaceCompare(String S, String T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;

        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S.charAt(i) == '#') {
                    skipS++;
                    i--;
                } else if (skipS > 0) {
                    skipS--;
                    i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T.charAt(j) == '#') {
                    skipT++;
                    j--;
                } else if (skipT > 0) {
                    skipT--;
                    j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S.charAt(i) != T.charAt(j)) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--;
            j--;
        }
        return true;
    }
}

977.有序数组的平方

方法一
平方后直接排序

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i=0;i<nums.length;i++)
        {
            nums[i]=nums[i]*nums[i];
        }
        Arrays.sort(nums);
        return nums;
    }
}

法二:双指针

class Solution {
    public int[] sortedSquares(int[] nums) {
        /*双指针 平方后最大数只可能出现在左端或者右端
        所以双指针各在左右两端,找最大值,依次填入
        */
        int left=0,right=nums.length-1;
        int[] ans = new int[nums.length];
        int index=ans.length-1;
        while(left<=right)
        {

            if(nums[left]*nums[left]>nums[right]*nums[right])
            {
                ans[index]=nums[left]*nums[left];
                index--;
                left++;
            }
            else
            {
                ans[index]=nums[right]*nums[right];
                index--;
                right--;
            }
        }
        return ans;
    }
}

你可能感兴趣的:(JAVA学习,Leetcode,leetcode,算法)