[2016/07/02] LeetCode / Java - Day 10 -

318. Maximum Product of Word Lengths

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0.

Example 1:

Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]
Return 16
The two words can be "abcw", "xtfn".

Example 2:

Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"]
Return 4
The two words can be "ab", "cd".

Example 3:

Given ["a", "aa", "aaa", "aaaa"]
Return 0
No such pair of words.

思路:我的解法是渣渣。。然后看了Discuss,果然。。。会了bit manipulation就可以拯救世界啊!!!

public class Solution {
    public int maxProduct(String[] words) {
        //学好 bit manipulation,算法都不怕QAQ
		int n = words.length;
		if(n==1) return 0;
		int[] conv = new int[n];
		int max= 0;
		for(int i=0;i<n;i++){
			for(int j=0;j<words[i].length();j++){
				//这句话的意思实际上是把conv[i]转化成了一个存储a~z字母是否存在于words[i]中的26位数组
				//如果words[i]中有'a'字母,那么conv[i]倒数第一位是1,如果'b',倒数第二位是1,以此类推
				//如果要判断两个字符串中是否有字母重复,只要判断conv[i]&conv[j]是否等于0就可以了,多么巧妙!
				conv[i] = conv[i] | (1<<words[i].charAt(j)-'a');				
			}
			for(int j=0;j<i;j++){
				if((conv[i] & conv[j]) == 0 )
					max = Math.max(max, words[i].length() * words[j].length());
			}
		}
		return max;
    }
}

51. N-Queens & 52. N-Queens II

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]

思路:学算法的一定要做这道题!我却这么晚才做。。不过好歹磨了两个小时,也算是完全自己做出来的吧= =(对我就是这么弱(。・・)ノ)

因为一个是输出结果,一个是输出个数,基本没什么差,就一起说了。

基本思路就是用深搜。从第一行开始放置一个皇后,然后用hasPut List存储已经放置的格子号(0~n*n-1),每次放下一个皇后的时候,判断是不是处在别的皇后的攻击范围内,如果不可以放就检测下一个。如果可以放,那么就加入hasPut,如果没有放完,就进行下一次深搜。深搜完回来要注意清除这次的操作,倒退一下hasPut List中这次添加进去的部分。然后= =嗯,好像也没别的什么注意的了,我写的输出结果的程序(下面第一个程序)中,输出个数的统计不太对,见第二个程序。

1/ 输出结果程序

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

public class Solution {
    public List<List<String>> solveNQueens(int n) {
    	int soluNum=0;
    	List<Integer> hasPut = new ArrayList<Integer>();
    	List<List<String>> result = new ArrayList<List<String>>();
    	//在第0(putNum)行开始放置一个皇后
    	dfs(0,n,soluNum, hasPut, result);
		return result;
        
    }
	private static void dfs(int putNum, int n, int soluNum, List<Integer> hasPut, List<List<String>> result) {
		// 在棋盘上寻找可放置的位置
		for(int i=0;i<n;i++){
			//如果该位置可以放置
			if(canPut(putNum,i,n,hasPut)){
				hasPut.add(putNum*n+i);
				if(putNum==n-1){
					//所有的放置成功
					soluNum++;
					//调用输出函数
					result.add(printQ(n,hasPut));		
					hasPut.remove(putNum);
				}else{
					dfs(putNum+1,n, soluNum, hasPut, result);
					hasPut.remove(putNum);
				}
			}
		}		
	}
	//判断(putNum, i)是否与已放置的冲突
	private static boolean canPut(int putNum, int i,int n, List<Integer> hasPut) {
		for(int lll=0;lll<hasPut.size();lll++){
			int x=hasPut.get(lll);
			int p = x/n;
			int q=  x%n;
			if(putNum==p || i==q || putNum-p == i-q || putNum-p==q-i)
				return false;
		}
		return true;
	}
	private static List<String> printQ(int n, List<Integer> hasPut) {
		List<String> ls = new ArrayList<String>();
		for(int i=0;i<n;i++){
			String line = "";
			int jn= hasPut.get(i)-i*n;
			for(int j=0;j<n;j++){
				if(j==jn)
					line+="Q";
				else line+=".";
			}
			ls.add(line);
		}
		return ls;
	}
}
2/ 输出个数程序

public class Solution {
public int totalNQueens(int n) {
    	int soluNum=0;
    	List<Integer> hasPut = new ArrayList<Integer>();
    	//在第0(putNum)行开始放置一个皇后
    	soluNum = dfs(0,n,soluNum, hasPut);
		return soluNum;
    }
	private static int dfs(int putNum, int n, int soluNum, List<Integer> hasPut) {
		// 在棋盘上寻找可放置的位置
		for(int i=0;i<n;i++){
			//如果该位置可以放置
			if(canPut(putNum,i,n,hasPut)){
				hasPut.add(putNum*n+i);
				if(putNum==n-1){
					//所有的放置成功
					soluNum++;
					hasPut.remove(putNum);
				}else{
					soluNum = dfs(putNum+1,n, soluNum, hasPut);
					hasPut.remove(putNum);
				}
			}
		}
		return soluNum;
	}
	//判断(putNum, i)是否与已放置的冲突
	private static boolean canPut(int putNum, int i,int n, List<Integer> hasPut) {
		for(int lll=0;lll<hasPut.size();lll++){
			int x=hasPut.get(lll);
			int p = x/n;
			int q=  x%n;
			if(putNum==p || i==q || putNum-p == i-q || putNum-p==q-i)
				return false;
		}
		return true;
	}
}
哦对了还有个问题就是,它的Judge输入是连续的,所以你不能在Solution类里声明全局静态变量让所有方法调用,所以我就只能麻烦的不停传参数了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值