经典算法问题之指针碰撞系列

本文涵盖多种数组及字符串操作的算法题目解答,包括数组排序、合并、查找特定元素及字符串处理等,提供了详细的实现代码与思路分析。

注释(Q:question、A:answer、C:code)
Q(1):数组里面只有0,1,2,排成顺序的数组
A:最简单的方法是遍历(简单到不敢相信,当然这不是最好的方法);
三路快排的方法。
C:

/**三路快排
 * 数组里面有3种数字,0,1,2
 * 排成顺序
 * 时间复杂度 o(n)
 * 空间为 o(1)
 */
public static void threeWay(int []array){
    int zero = -1;
    int two = array.length;

    for(int i = 0 ; i < two ; ){

        if(array[i] == 1){
            i++;
        }
        else if(array[i] == 2){
            swap(array,--two,i);
        }
        else{
            swap(array,++zero,i++);
        }
    }
    for(int a:array)
        System.out.print(a+" ");
    System.out.println();

}
public static void swap(int []array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

以下是在leetcode上面做过的题,给出题号和解答
/**ques:88
* 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
思考: 有序数组,nums空间足够大,通过在末尾进行比较,填值,减小了开销。
时间复杂度:O(n)
空间复杂度 O(m),没有额外的空间开销
*/
public void merge(int[] nums1, int m, int[] nums2, int n) {

    int i = m-1;
    int j = n-1;
    int index = n+m-1;

    while(i>=0 && j>=0){
        if(nums1[i] >= nums2[j])
            nums1[index--] = nums1[i--];
        else{
            nums1[index--] = nums2[j--];
        }
    }
    while(i>=0){
        nums1[index--] = nums1[i--];
    }
    while(j>=0){
        nums1[index--] = nums2[j--];
    }
    System.out.println("[");
    int k;
    for(k = 0;k< nums1.length-1 ;k++){
        System.out.println(nums1[k]+",");
    }
    System.out.println(nums1[k]+"]");

}

/**
 * question:215. 数组中的第K个最大元素
 * 描述:在未排序的数组中找到第 k 个最大的元素。
 * 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
 *
 */
public static int findKthLargest(int[] nums, int k) {

    return findKthLargest(nums,0,nums.length-1,k);
}

public static int findKthLargest(int[] nums,int low,int high, int k) {

    int pos = quickPanition(nums,low,high);
    if(k == pos-low+1)
        return nums[pos];
    else if(k > pos-low+1) /**在后半段**/
        return findKthLargest(nums,pos+1,high,k-pos+low-1);
    else
        return findKthLargest(nums,low,pos-1,k);
}

public static int quickPanition(int []nums,int low,int high){

    int l = low;
    int h = high;
    int pivot = nums[low];
    while(l<h){
        while(l<h&&nums[h]<=pivot)
            h--;
        //if(l<h){
            swap(nums,l,h);
            //l++;
        //}
        while(l<h&&nums[l]>=pivot)
            l++;
        //if(l<h){
            swap(nums,l,h);
            //h--;
        //}
    }
    return l;
}

public static void swap(int []array,int i,int j){
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

/**
 * quse: 167. 两数之和 II - 输入有序数组
 */
public int[] twoSum(int[] numbers, int target) {

    int []res={};
    int l = 0;
    int h = numbers.length - 1;
    while(l<h){
        int sum = numbers[l] + numbers[h];
        if(sum == target){
            res = new int []{l+1,h+1};
            return res;
        }
        else if(sum < target){
            l++;
        }
        else{
            h--;
        }
    }
    return res;
}

/**
 *question:125. 验证回文串
 */
public static boolean isPalindrome(String s) {

    int l = 0;
    int h = s.length()-1;
    while(l<=h){
        System.out.println("l="+l+" "+"h="+h);
        char lc = s.charAt(l);
        char hc = s.charAt(h);
        int rsl = isCharOrDigit(lc);
        int rsh = isCharOrDigit(hc);
        if(rsl < 0)
            l++;
        else if(rsh < 0)
            h--;
        else{
            if(rsl <= 57 && rsl ==rsh){
                l++;
                h--;
            }
            else if(rsl > 57 && rsh > 57){
                int temp = Math.abs(rsl-rsh);
                if(temp == 0 || temp == 32){
                    l++;
                    h--;
                }
                else
                    return false;
            }
            else
                return false;
        }
    }
    return true;
}

public static int isCharOrDigit(char c){

    if(c>='0'&&c<='9'||c>='a'&&c<='z'||c>='A'&&c<='Z')
        return (int)c;
    return -1;
}


/**
 *question:344 请编写一个函数,其功能是将输入的字符串反转过来。
 */
public String reverseString(String s) {
    char []array = s.toCharArray();
    int l = 0,h = array.length - 1;
    while(l<=h){
        char temp = array[l];
        array[l++] = array[h];
        array[h--] = temp;
    }
    return String.valueOf(array);
}

/**
 * question:345 反转字符串中的元音字母
 */
public String reverseVowels(String s) {

    char [] array = s.toCharArray();
    int l = 0;
    int h = s.length() - 1;
    while(l < h){
        char lc = s.charAt(l);
        char hc = s.charAt(h);
        if(!isVowels(lc))
            l++;
        else if(!isVowels(hc))
            h--;
        else{
            swap(array,l,h);
            l++;
            h--;
        }

    }
    return String.valueOf(array);
}

public boolean isVowels(char c){
    if((int)c<97)
        c = (char)((int)c+32);
    if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
        return true;
    return false;
}

public void swap(char []array,int i,int j){
    char temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

/**
 * question:11 盛最多水的容器
 */
public static int maxArea(int[] height) {

    int area  = 0;
    int low = 0;
    int high = height.length - 1;
    while(low < high){
        int lz = height[low];
        int hz = height[high];
        int max = lz < hz ? lz : hz;
        if(area < max * (high - low)){
            area = max * (high - low);
        }
        if(lz < hz)
            low++;
        else
            high--;
    }
    return area;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值