目录

蛮力法的定义:

蛮力法的适用场景:

1、搜索所有的解空间:

2、搜索所有的路径:

3、直接计算:

4、模拟和仿真:

蛮力法的具体应用案例:

1、简单选择排序和冒泡排序:

2、求解最大连续子序列和问题:

3、求解幂集问题:

4、求解全排列问题:

5、求解组合问题:

6、求解迷宫问题:


蛮力法的定义:

对问题中的所有可能状态都进行测试,直到找到解或将全部可能状态都测试为止。

蛮力法的适用场景:

1、搜索所有的解空间:

问题的解存在于规模不大的解空间中。解决这类问题一般是找出某些满足特定条件或要求的解。使用蛮力法就是把所有的解都列出来,从中选出符合要求的解。

2、搜索所有的路径:

这类问题中不同的路径对应不同的解,需要找出特定解。使用蛮力法搜索所有可能的路径并计算路径对应的解,找出特定解。

3、直接计算:

基于问题的描述直接进行计算。

4、模拟和仿真:

根据问题要求直接模拟或仿真。

蛮力法的具体应用案例:

1、简单选择排序和冒泡排序:

简单选择排序代码展示:

package test;

public class Test {
	public static void main(String[] args) {
		int[] a= {7,3,5,9,4,2};
		sort(a);
		for(int i=0;i<a.length;i++)
			System.out.println(a[i]);
	}
	private static void sort(int[] nums) {
		for(int i=0;i<nums.length;i++) {
			int k=i;
			for(int j=i+1;j<nums.length;j++)
				if(nums[k]>nums[j])
					k=j;
			if(k!=i) {
				int temp=nums[i];
				nums[i]=nums[k];
				nums[k]=temp;
			}
		}
	}
}

冒泡排序代码展示:

package test;

public class Test {
	public static void main(String[] args) {
		int[] a= {7,3,5,9,4,2};
		sort(a);
		for(int i=0;i<a.length;i++)
			System.out.println(a[i]);
	}
	private static void sort(int[] nums) {
		for(int i=0;i<nums.length;i++) {
			boolean exchange=false;
			for(int j=nums.length-1;j>i;j--) {
				if(nums[j]<nums[j-1]) {
					int temp=nums[j];
					nums[j]=nums[j-1];
					nums[j-1]=temp;
					exchange=true;
				}
			}
			if(!exchange)
				break;
		}
	}
}

2、求解最大连续子序列和问题:

LeetCode 第53题 最大子数组和

剑指 Offer 42 连续子数组的最大和

思路:用一个变量sum表示当前子数组的最大和,用另一个变量max表示最终子数组最大和,然后从头到尾扫描整个数组,每扫描一个元素之前先判断sum是否小于0,若小于则将sum置为0;然后将sum加上扫描的元素,最后max取sum和max中的最大值。扫描一遍数组,答案就出来了,此方法的时间复杂度为O(n),而分治法解决此问题的时间复杂度为

,故此方法效率更高。

完整代码展示:

package leetcode_7;

public class T_O_42 {
	public static void main(String[] args) {
		int[] a= {-2,1,-3,4,-1,2,1,-5,4};
		System.out.println(maxSubArray(a));
	}
	public static int maxSubArray(int[] nums) {
		int max=nums[0],sum=nums[0];
		for(int i=1;i<nums.length;i++) {
			if(sum<0)
				sum=0;
			sum+=nums[i];
			max=Math.max(max, sum);
		}
		return max;
	}
}

3、求解幂集问题:

面试题 08.04 幂集

思路:采用增量穷举法求解,此处借助了ArrayList。可以通过遍历或递归实现。

完整代码展示(遍历实现):

package leetcode_7;

import java.util.ArrayList;
import java.util.List;

public class T_mst0804 {
	public static void main(String[] args) {
		int[] a= {1,2,3};
		System.out.println(subsets(a));
	}
	public static List<List<Integer>> subsets(int[] nums){
		List<List<Integer>> ans=new ArrayList();
		List<Integer> p=new ArrayList();
		ans.add(p);
		for(int i=0;i<nums.length;i++) {
			int n=ans.size();
			for(int j=0;j<n;j++) {
				List<Integer> t=new ArrayList(ans.get(j));
				t.add(nums[i]);
				ans.add(t);
			}
		}
		return ans;
	}
}

完整代码展示(递归实现):

package leetcode_7;

import java.util.ArrayList;
import java.util.List;

public class T_mst0804 {
	public static void main(String[] args) {
		int[] a= {1,2,3};
		System.out.println(subsets(a));
	}
	public static List<List<Integer>> subsets(int[] nums){
		List<List<Integer>> ans=new ArrayList();
		ans.add(new ArrayList());
		f(nums,0,ans);
		return ans;
	}
	private static void f(int[] nums,int n,List<List<Integer>> ans) {
		if(n>=nums.length)
			return ;
		int count=ans.size();
		for(int i=0;i<count;i++) {
			List<Integer> t=new ArrayList(ans.get(i));
			t.add(nums[n]);
			ans.add(t);
		}
		f(nums,n+1,ans);
	}
}

4、求解全排列问题:

LeetCode 第46题 全排列

思路:也是采用增量穷举法求解,此处借助了LinkedList。同样也可以通过遍历或递归实现。

完整代码展示(遍历实现):

package leetcode_7;

import java.util.LinkedList;
import java.util.List;

public class T_46 {
	public static void main(String[] args) {
		int[] a= {1,2,3};
		System.out.println(permute(a));
	}
	public static List<List<Integer>> permute(int[] nums){
		List<List<Integer>> ans=new LinkedList();
		List<Integer> p=new LinkedList();
		p.add(nums[0]);
		ans.add(p);
		for(int i=1;i<nums.length;i++) {
			int n=ans.size();
			for(int j=0;j<n;j++) {
				List<Integer> t=new LinkedList(ans.get(0));
				ans.remove(0);
				int m=t.size();
				for(int k=0;k<=m;k++) {
					List<Integer> q=new LinkedList(t);
					q.add(k, nums[i]);
					ans.add(q);
				}
			}
		}
		return ans;
	}
}

(ArrayList与LinkedList的区别:ArrayList使用顺序存储结构存储对象元素,故其查找、遍历元素快,插入、删除元素慢;LinkedList使用链表结构存储元素,故其插入、删除元素快,查找、遍历元素慢。)

5、求解组合问题:

LeetCode 第77题 组合

思路:采用递归解决,大问题:从n个数中找k个数,小问题:从m个数中找k-1个数。(k-1<=m<n)当k=0时说明这是其中的一个组合,将其加入所求集合中。

完整代码展示:

package leetcode_7;

import java.util.LinkedList;
import java.util.List;

public class T_77 {
	public static void main(String[] args) {
		System.out.println(combine(4,2));
	}
	public static List<List<Integer>> combine(int n, int k){
		List<List<Integer>> ans=new LinkedList();
		List<Integer> p=new LinkedList();
		f(n,k,ans,p);
		return ans;
	}
	private static void f(int n,int k,List<List<Integer>> ans,List<Integer> t) {
		if(k==0) {
			ans.add(t);
			return ;
		}
		for(int i=k;i<=n;i++) {
			List<Integer> q=new LinkedList(t);
			q.add(i);
			f(i-1,k-1,ans,q);
		}
	}
}

6、求解迷宫问题:

问题:有一个8x8的迷宫如下图所示,其中O表示通路方块,X表示障碍方块。假设入口位置为(0,0),出口为右下角方块位置(7,7)。设计一个程序求指定入口到出口的一条迷宫路径。

迷宫

O

X

X

X

X

X

X

X

O

O

O

O

O

X

X

X

X

O

X

X

O

O

O

X

X

O

X

X

O

X

X

O

X

O

X

X

X

X

X

X

X

O

X

X

O

O

O

X

X

O

O

O

O

X

O

O

X

X

X

X

X

X

X

O

思路:采用枚举的思想解决此题,可通过DFS或BFS去实现。

完整代码展示(DFS):

package test;

public class Test3 {
	public static void main(String[] args) {
		char[][] maze={{'O','X','X','X','X','X','X','X'},
				 	   {'O','O','O','O','O','X','X','X'},
				 	   {'X','O','X','X','O','O','O','X'},
				 	   {'X','O','X','X','O','X','X','O'},
				 	   {'X','O','X','X','X','X','X','X'},
				 	   {'X','O','X','X','O','O','O','X'},
				 	   {'X','O','O','O','O','X','O','O'},
				 	   {'X','X','X','X','X','X','X','O'}};
		dfs(0,0,maze);//设置起点位置为左上角
		}
	private static void dfs(int x,int y,char[][] maze) {
		int row=maze.length,col=maze[0].length;
		if(x==col-1&&y==row-1) {//设置终点的位置为右下角
			for(int i=0;i<row;i++) {
				for(int j=0;j<col;j++)
					System.out.print(maze[i][j]+" ");
				System.out.println();
			}
			return ;
		}
		int[] H= {0,1,0,-1};
		int[] V= {-1,0,1,0};
		for(int k=0;k<4;k++) {
			if(0<=x&&x<col&&0<=y&&y<row&&maze[x][y]=='O') {
				maze[x][y]='T';
				dfs(x+H[k],y+V[k],maze);
				maze[x][y]='O';//如果退回来就恢复迷宫此处初始值
			}
		}
	}
}