我有一个数组,让我们说{7,6,4,2}
。
我需要高效算法来查找在给定元素之后出现n
个较小数字的次数,其中每个元素都小于前一个元素。
例如:n=3
,a[i]>a[j]>a[k]
和i < j < k
。此处的输出应为{7,6,4}
,{7,6,2}
和{6,4,2}
。
我有一个包含3个for循环的简单算法,但显然具有O(n^3)
复杂度的解决方案是不可行的。
以下是我为n=3
创建的示例代码。
// Array is initialized and given values. Size of Array is n1
for(int i=0;i<n1-2;i++)
{
for(int j=i+1;j<n1-1;j++)
{
if(a[j]<a[i])
{
for(int k=j+1;k<n1;k++)
{
if(a[k]<a[j])
{
cnt++;
}
}
}
}
}
您能否将我链接到我可以使用的算法或在下面提供算法。 JAVA首选。
答案 0 :(得分:1)
如果你选择{7,6,11,2},你可以构建一个图形,其中节点是7,6,11和2,并且只有当另一个节点索引更大并且它具有指向边缘时才有。 s值较小。构建这样的图应该是O(len(a)^ 2)。
构建图形后,您可以编写一个递归函数,计算它可以达到3个连续节点的次数。复杂性是O(n * len(a))。
我的解决方案(仅考虑第一个元素,但它很容易适应):
#include <stdio.h>
#include <stdlib.h>
struct succ {
struct node* node;
struct succ* next;
};
struct node {
struct succ* successors;
int value;
int index;
};
struct node* build_graph(int a[], int n1) {
struct node* graph = malloc(n1 * sizeof(struct node));
int i, j;
for (i = 0; i < n1; i++) {
graph[i].value = a[i];
graph[i].index = i;
}
for (i = 0; i < n1; i++) {
for (j = i; j < n1; j++) {
if (a[i] > a[j]) {
struct succ *el = malloc(sizeof(struct succ));
el->node = &graph[j];
el->next = graph[i].successors;
graph[i].successors = el;
}
}
}
return graph;
}
int browse(struct node* graph, int i, int n) {
if (n == 0) return 1;
struct succ *aux = graph[i].successors;
int cnt = 0;
while (aux) {
cnt += browse(graph, aux->node->index, n - 1);
aux = aux->next;
}
return cnt;
}
int main() {
//int a[] = {7, 6, 11, 2};
int a[] = {7, 6, 4, 2};
struct node* graph = build_graph(a, 4);
printf("%d\n", browse(graph, 0, 2));
return 0;
}
答案 1 :(得分:1)
import java.util.*;
import java.io.*;
class CDVA1510
{
public static void main(String[] args) throws Exception
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in))
int n=Integer.parseInt(br.readLine());
String[]a1=br.readLine().split(" ");
long[] a=new long[a1.length()];
for(int j=0;j<a.length();j++)
{
a[j]=Integer.parseInt(a1[j]); //Storing the values
}
ArrayList<Long>al=new ArrayList<Long>();//Sorted List for storing the values
ArrayList<Integer>nos=new ArrayList<Integer>();//List for adding number of numbers before the given number with which combinations are possible
int []no=new int[n];
for(int j=n-1;j>=0;j--)
{
al.add(a[j]);
Collections.sort(al);
if(al.indexOf(a[j])>=2)//Getting postion of element and since implementation is specific, checking if it it greater than or equal to 2 so that x(this number) choose 2 is possible
{
nos.add(al.indexOf(a[j]));
//System.out.println(a[j]);
}
}
int cnt=0;
for(int j=0;j<nos.size();j++)
{
cnt += COM(nos.get(j));
}
System.out.println(cnt);
}
private static long COM(long a)//Method for getting the combinations. Again specific for n=3
{
int x=1,y=1;
for(int i=1;i<=a;i++)
{
if(i<=a-2)
{
x = x * i;
y = y * i;
}
else
{
x=x*i;
}
}
return((x)/(y*2));
}
}