找到右边最小的元素

时间:2016-07-23 07:15:31

标签: java arrays algorithm

我正在尝试解决一个算法,其中我必须在数组右侧找到最小的元素reference

对于以下数组中的实例 输入:[8,58,71,18,31,32,63,92,          43,3,91,93,25,80,28]

第一元素8右侧的最小元素是18,因为第二元素58是63&等等。我需要帮助解决算法的逻辑。我打算先用蛮力解决,复杂度为O(n ^ 2)。

我现在写的代码在

之下
SELECT product.*
FROM product 
    INNER JOIN category ON product.category_id = category.category_id
WHERE category.category_name LIKE '%keyword%'

我已经创建了第二个数组tmpArr来获取元素右边的所有值,这些值大于它。可能会排序那个数组然后&取第一个值。但这种逻辑似乎对我不好。

另一种解决方案可以是

public class Tmp {

public static void main(String[] args) {

    int[] arr = { 8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28 };
    int[] tmpArr = new int[arr.length];
    int pos = 0;
    int k=0;

    for (int i = 0; i < arr.length-1; i++) { 
        //int next = arr[i];
        for (int j = i + 1; j < arr.length; j++) {
            if ((arr[j] > arr[i])) {
             tmpArr[k]=arr[j]; // take all the values to the right of the element which are greater than it
             k++;
            }
        }

任何人都可以帮助提供更简单的解决方案吗?

6 个答案:

答案 0 :(得分:3)

要解决问题O(n log n),您可以使用TreeSet并从右向左移动。

TreeSet<Integer> set = new TreeSet<Integer>();
for (int i = ar.length - 1; i >= 0; --i) {
    set.higher(ar[i]); // what you need, may be null
    set.add(ar[i]);
}

答案 1 :(得分:2)

第二个片段几乎没问题:

for (int i = 0; i < arr.length; i++) { // (1)
    int leastGreater = -1; // (2)
    for (int j = i + 1; j < arr.length; j++) {
        if ((arr[j] > arr[i])) {
            if(leastGreater == -1 || arr[j]<leastGreater){ // (3)
                leastGreater = arr[j];
            }
        }
    }
    arr[i] = leastGrater; // (4)
}
  1. 我们还需要设置数组的最后一个元素,让循环遍历整个数组
  2. 如果找不到任何内容,则该值应为-1,因此初始化为
  3. 如果还没有找到,
  4. 还需要更换
  5. 将新值设置为数组

答案 2 :(得分:2)

这应该有效

int a[]={8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28};
    int n=a.length;
    for(int i=0;i<n-1;i++){
        int diff=Integer.MAX_VALUE;
        int leastGreater=Integer.MAX_VALUE;
        for(int j=i+1;j<n;j++){
            if(a[j]-a[i]>0&&diff>a[j]-a[i]){
                diff=a[j]-a[i];
                leastGreater=a[j];
            }
        }
        if(leastGreater==Integer.MAX_VALUE){
            System.out.println("Not Found for index "+i);
        }else{
            System.out.println(leastGreater+" found for index "+i);
        }
    }

它检查当前元素右边的差异,该元素应该> 0,即右元素应大于当前元素。

答案 3 :(得分:2)

使用二进制搜索和两种指针技术。首先对数组进行排序,如果存在,则此函数返回O(log n)中的最小索引,否则返回-1

int LeasterGreater(int[] a, int value, int left, int right) {
    int low = left;
    int high = right;
    while (low != high) {
        int mid = (low + high) / 2;
        if (a[mid] <= value) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }
    if (low == right) {
        return -1;
    }
    return low;
}

示例1:

int[] arr = {8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28};
    Arrays.sort(arr);
    int leastGreaterIndex = LeasterGreater(arr, 58, 0, arr.length);
    if (leastGreaterIndex >= 0) {
        System.out.println(arr[leastGreaterIndex]);
    } else {
        System.out.println("doesn't exist!");
    }

输出:

  

63

示例2:

int[] arr = {8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28};
    Arrays.sort(arr);
    int leastGreaterIndex = LeasterGreater(arr, 93, 0, arr.length);
    if (leastGreaterIndex >= 0) {
        System.out.println(arr[leastGreaterIndex]);
    } else {
        System.out.println("doesn't exist!");
    }
  

不存在!

答案 4 :(得分:1)

这在O(n)中非常容易解决,只需查看当前预期的数字是否在当前解决方案与输入对应的数字之间,然后就可以更新解决方案:

public static int getNextIntToTheRight(int[] arr, int index) {
  int ret = Integer.MAX_VALUE; // initialize
  for (int i = index + 1; i < arr.length; i++) // for all items to the right of index
    if (arr[i] < ret && arr[i] > arr[index]) // if the inspected item is better
      ret = arr[i]; // update on the fly
  return ret; // this is now the solution, if there is any, otherwise Integer.MAX_VALUE
}

答案 5 :(得分:0)

可以使用当前/最小值的位置的临时变量大于目标和一个循环。布尔值是可选的,更清晰。也可以使用temp var初始化为-1&amp;用作标志代替布尔值。 对于更大的阵列和许多调用,使用一个循环更快。 Full source

        int[] arr = { 8, 58, 71, 18, 31, 32, 63, 92, 43, 3, 91, 93, 25, 80, 28 };
        // Test cases
        ap.findLeasterGreater(arr, 0);
        ap.findLeasterGreater(arr, 1);
        ap.findLeasterGreater(arr, 11);
        ap.findLeasterGreater(arr, 6);
        // without boolean
        ap.findLeasterGreater2(arr, 0);
        ap.findLeasterGreater2(arr, 1);
        ap.findLeasterGreater2(arr, 11);
        ap.findLeasterGreater2(arr, 6);

    /*
     * One loop L-R, check if first greater val encountered. Ini currGreater, when a new value that > orig but < currGreater, use that as
     * the currGreater Using the location of curr greater so can return that. More useful.
     */
    int findLeasterGreater(int[] arr, int loc) {
        int nextGreaterLoc = -1;
        boolean first = true;
        for (int i = loc + 1; i < arr.length; i++) {
            if (first && arr[loc] < arr[i]) {
                first = false;
                nextGreaterLoc = i;
            } else if (arr[loc] < arr[i] && arr[nextGreaterLoc] > arr[i]) {
                nextGreaterLoc = i;
            }
        }
        if (nextGreaterLoc == -1) {
            System.out.println("Not found a value bigger than " + arr[loc] + " (after location " + loc + ")");
        } else {
            System.out.println("Found a value bigger :" + arr[nextGreaterLoc] + " at location " + nextGreaterLoc + " bigger than "
                    + arr[loc] + " (after location " + loc + ")");
        }
        return nextGreaterLoc;
    }

    /*
     * with 1 less local var - no boolean
     */
    int findLeasterGreater2(int[] arr, int loc) {
        int nextGreaterLoc = -1;
        for (int i = loc + 1; i < arr.length; i++) {
            if (nextGreaterLoc == -1 && arr[loc] < arr[i]) {
                nextGreaterLoc = i;
            } else if (nextGreaterLoc > -1 && arr[loc] < arr[i] && arr[nextGreaterLoc] > arr[i]) {
                nextGreaterLoc = i;
            }
        }
        if (nextGreaterLoc == -1) {
            System.out.println("Not found a value bigger than " + arr[loc] + " (after location " + loc + ")");
        } else {
            System.out.println("Found a value bigger :" + arr[nextGreaterLoc] + " at location " + nextGreaterLoc + " bigger than "
                    + arr[loc] + " (after location " + loc + ")");
        }
        return nextGreaterLoc;
    }
}