数组的算法思想(一)

175 阅读2分钟

双指针操作数组

数组的基本操作,在数组的循环中,不断的定位符合条件的子数组

  • 两个指针left和right
  • 固定一个移动另一个,始终保持left <= right
例题1:由一个字符串由点和字母(大写或小写字母)组成,将字符串依次分成点的集合和字母集合,将字符串反转,但是字母的顺序不变,如:
输入:"aFC...b..cfb.."
输出:"..cfb..b...aFC"
class Test{
    
    public static String getString(String str) {
        //将字符串全部反转
        char[] chars = str.toCharArray();
        reverseChars(chars ,0 ,chars.length-1);
        //利用双指针将每个单词反转
        int i = 0;
        int j = 0;
        while (j < chars.length) {
            //找到第一个字符
            while (i < chars.length && chars[i] == '.') {
                i++;
            }
            j = i;
            //找到末位置(由于前面i==j,第一次循环都成立,则j无论怎样都大于i)
            while (j < chars.length && chars[j] != '.') {
                j++;
            }
            reverseChars(chars ,i ,j-1);
            i = j;
        }
        return new String(chars);
    }

    private static char[] reverseChars(char[] chars ,int i ,int j){
        while (i < j) {
            char temp = chars[i];
            chars[i++] = chars[j];
            chars[j--] = temp;
        }
        return chars;
    }
}


滑动窗口

滑动窗口算法用于数组中的连续子元素问题,需要用到双指针操作数组。可以将循环嵌套的问题转化为单循环的问题,降低时间复杂度

  • 需要两个指针left和right
  • 通常需要一个指针固定,另一个指针不断累加
  • 窗口可由right不断累加扩大
  • 窗口也可由left不断累加减小
例题1:没有重复字符的子字符的最大长度:给一个字符串,获得没有重复字符的最长子字符的长度
class Test{

    public int getInt(String s){
        HashSet<Character> set = new HashSet<>();
        int left = 0;
        int right = 0;
        int result = 0;
        while (left < s.length() && right < s.length()) {
            if (!set.contains(s.charAt(right))) {
                set.add(s.charAt(right++));
                result = Math.max(result ,right - left);
            }else {
                set.remove(s.charAt(left++));
            }
        }
        return result;
    }
    
}