[재귀 + 역 추적] 배열 요소의 조합, 배열 및 전체 배열 구현

목차

하나, 배열 요소의 조합

둘째, 배열 요소의 전체 배열

셋째, 배열 요소의 순열 및 조합

안녕하세요, 잘 지내세요, 나는 작은 회색 원숭이입니다! 버그를 작성할 수있는 슈퍼 프로그래머!

최근에 블루 브리지 컵 관련 테스트 문제를 수행 할 때 순열 및 배열 요소 조합의 사용이 매우 광범위하고 일반적인 순열 및 조합 질문 유형도 데이터 구조 및 알고리즘의 전형적인 예라는 것을 발견했습니다. 그래서 오늘 저는 공유 할 것입니다 일반적인 개발 프로세스에서 순열 및 조합의 여러 유형과 솔루션이 자주 사용됩니다.

하나, 배열 요소의 조합

n 개 요소 배열 arr (순서 및 반복 없음에 관계없이)에서 m 개의 숫자를 가져 와서 새 배열 newarr에 배치하는 경우 일반적인 아이디어는 재귀 아이디어를 사용하는 것입니다.

  1. 배열 arr에서 n 개의 숫자를 취한 다음, arr의 첫 번째 숫자를 newarr의 첫 번째 요소로 취할 수 있습니다.
  2. arr의 첫 번째 요소를 꺼낸 후 재귀 구현을 사용하여 다음 n-1 요소 (첫 번째 단계의 하위 문제) 에서 m-1 요소를 꺼냅니다 .
  3. 0 개의 요소를 제거해야 할 때 결합 된 작업이 완료됩니다.
  4. 첫 번째 단계로 돌아가서 for 루프를 사용하여 두 번째 요소를 꺼내고 (다음 조합 시작) 총 nm 번 루프합니다.

특정 구현은 다음 함수에서 볼 수 있으며 직접 호출하고 사용할 수 있습니다.

    /**
	 * 在数组中选取n个数进行组合(不考虑顺序且数据不重复)
	 * @param 待处理的数组
	 * @param newarr 组合后得到的数组
	 * @param k  从哪一个下标的元素开始取
	 * @param n 需要取出元素的个数
	 * */
	private static void combination(int[] arr,int[] newarr, int k,int n) {
		//当需要取出的元素个数是0时,说明组合完成
		if (n==0) {
			for (int i = 0; i < newarr.length; i++) {
				System.out.print(newarr[i]);
			}
			System.out.println();
			return;
		}
		for (int i = k; i <= arr.length-n; i++) {		
			newarr[newarr.length-n] = arr[i];	//将提取出来的数依次放到新数组中
			combination(arr, newarr,i+1, n-1);	//按照同样的方法从剩下的元素中选出n-1个元素
		}
	}

테스트 케이스 :

public static void main(String[] args) {
		int[] arr = {1,2,3,4};		//待处理的数组
		int n = 3;	//取出元素的个数
		int[] newarr = new int[n];		//存放结果的数组
		combination(arr, newarr, 0, n);
	}

둘째, 배열 요소의 전체 배열

n 개의 숫자로 배열 arr의 전체 배열을 위해 사용되는 아이디어는 재귀와 역 추적입니다.

  1. n 개의 요소를 완전히 정렬하고 첫 번째 요소를 다음 요소와 차례로 교환하고 첫 번째 요소를 결정합니다.
  2. 다음 n-1 요소의 전체 배열 (첫 번째 단계의 하위 문제로 간주 될 수 있음) 은 재귀로 구현됩니다.
  3. 배열 요소의 순서가 중단되는 것을 방지하기 위해 교환 된 요소를 다시 교체하십시오 (역 추적 사고).

특정 구현은 다음 기능을 볼 수 있습니다 (직접 사용할 수 있음)

    /**
	 * 对数组中所有的元素进行全排列
	 * @param arr 待排列的数组
	 * @param k 确定第几个元素,是下标,从0开始
	 * */
	private static void f(int[] arr, int k) {
		//当k等于数组的长度时,说明排列完成
		if (k == arr.length) {
			//将排列好的数组输出
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i]);
			}
			System.out.println();
		}
		
		for (int i = k; i < arr.length; i++) {
			//将待确定的元素位置和后面的元素互换
			int t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
			
			//递归(确定第k+1个元素)
			f(arr, k+1);
			
			//回溯,将调换后的元素重新调换回来
			t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
		}	
	}

테스트 케이스 :

public static void main(String[] args) {
		int[] arr = {1,2,3,4};		//待处理的数组
		int n = 3;	//取出元素的个数
		int[] newarr = new int[n];		//存放结果的数组
		f(arr, 0);
	}

셋째, 배열 요소의 순열 및 조합

n 개 요소 배열 arr (순서 및 반복 없음에 관계없이)에서 m 개의 숫자를 꺼내고 n 개의 숫자를 완전히 순열 한 다음 순열을 달성하기 위해 n 개의 숫자에서 m 개의 숫자를 꺼내는 것에 대한 위의 이해를 통해 문제는 다음의 조합으로 볼 수 있습니다. 위의 두 가지 문제.

수학의 개념에 따르면 먼저 n 요소의 배열에서 m 요소를 선택한 다음 모든 m 요소를 배열 할 수 있습니다.

구현 방법은 다음과 같습니다.

    /**
	 * 数组中对n个数进行全排列
	 * @param 待处理的数组
	 * @param newarr 排列后得到的数组
	 * @param k  从哪一个下标的元素开始处理
	 * @param n 处理元素的个数
	 * */
	private static void pac(int[] arr,int[] newarr, int k,int n) {
		//当n=0时,说明选取的数的个数为0,也就是组合完成
		if (n==0) {
			f(newarr, 0);	//对组合到的新数组进行全排列
			return;
		}
		for (int i = k; i <= arr.length-n; i++) {		
			newarr[newarr.length-n] = arr[i];
			pac(arr, newarr,i+1, n-1);
		}
	}
	
	/**
	 * 对数组中所有的元素进行全排列
	 * @param arr 待排列的数组
	 * @param k 确定第几个元素,是下标,从0开始
	 * */
	private static void f(int[] arr, int k) {
		//当k等于数组的长度时,说明排列完成
		if (k == arr.length) {
			//将排列好的数组输出
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i]);
			}
			System.out.println();
		}
		
		for (int i = k; i < arr.length; i++) {
			//将待确定的元素位置和后面的元素互换
			int t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
			
			//递归(确定第k+1个元素)
			f(arr, k+1);
			
			//回溯,将调换后的元素重新调换回来
			t = arr[k];
			arr[k] = arr[i];
			arr[i] = t;
		}	
	}

테스트 케이스 :

public static void main(String[] args) {
		int[] arr = {1,2,3,4};		//待处理的数组
		int n = 3;	//取出元素的个数
		int[] newarr = new int[n];		//存放结果的数组
		pac(arr,newarr,0, n);
	}

위의 세 가지 일반적인 유형의 순열 및 조합과 그 솔루션이 있습니다. 주요 아이디어는 재귀 및 역 추적을 사용하는 것입니다. 최적화 또는 결함이 있으며 수정하실 수 있기를 바랍니다.

기분이 좋아지고 좋아하고 팔로우하는 것을 잊지 마십시오!

Little Grey Ape가 함께 진행하여 함께 진행합니다!

추천

출처blog.csdn.net/weixin_44985880/article/details/113434593