题目一:洗衣机问题
第一步:先看sum%N
第二步:看第i台机器
一)左右都是负,至少 |左| + |右|
二)左右都是正,至少 max(|左|,|右|)
三)左负右正 ,至少max(|左|,|右|)
四)左正右负,至少max(|左|,|右|)
每个点算出答案,最痛的点就是瓶颈
public int findMinMoves(int[] machines) {
if(machines.length < 1 || machines == null){
return -1;
}
int sum = 0;
int N = machines.length;
for(int i = 0; i < machines.length;i++){
sum += machines[i];
}
if(sum % N != 0){
return -1;
}
int avg = sum/N;
int leftSum = 0;
int ans = 0;
for(int i = 0; i < machines.length;i++){
int leftRest = leftSum - i * avg;
int rightRest = (sum - leftSum - machines[i]) - (machines.length - i - 1) * avg;
if(leftRest < 0 && rightRest < 0 ){
ans = Math.max(ans, Math.abs(leftRest)+Math.abs(rightRest));
}else{
ans = Math.max(ans, Math.max(Math.abs(leftRest),Math.abs(rightRest)));
}
leftSum += machines[i];
}
return ans;
}
题目二:(宏观调度)
螺旋的方式打印矩阵
0 1 2 3
4 5 6 7
8 9 10 11
打印顺序 0 1 2 3 7 11 10 9 8 4 5 6
给一个左上角和右下角,实现函数 只打印这个框
public static void spiralOrderPrint(int[][] matrix){
int tR = 0;
int tc = 0;
int dR = matrix.length - 1;
int dC = matrix[0].length - 1;
while(tR <= dR && tC <= dC){
printEdge(matrix, tR++, tC++, dR--, dC--);
}
}
public static void printEdge(int[][] m, int a, int b, int c, int d){
if(a == c){
for(int i = b; i <= d; i++){
System.out.print(m[a][i] + " ");
}//横线
}else if(b == d){
for(int i = a; i <= c; i++){
System.out.print(m[i][b] + " ");
}//竖线
}else {
int curC = b;
int curR = a;
while(curC != d){
System.out.print(m[a][curC] + " ");
curC++;
}//往右
while(curR != c){
System.out.print(m[curR][d] + " ");
curR++;
}//往下
while(curC != b){
System.out.print(m[c][curC] + " ");
curC--;
}//往左
while(curR != a){
System.out.print(m[curR][b] + " ");
curR--;
}//往上
}
}
给定一个正方形矩阵,只用有限几个变量,实现矩阵中每个位置的数顺时针转动90度,比如下面的矩阵
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
调整为
12 8 4 0
13 9 5 1
14 10 6 2
15 11 7 3
先处理
0 1 2 3
4 7
8 11
12 13 14 15
分成三组
0 3 1 2
7 4
8 11
12 15 14 13
三组
假设现在的框左上角 a行b列 右下角 c行d列,共有d-b+1组
第一个for循环,规定有几组
第i组的第一个第二个第三个和第四个
1) m[a][b+i]
2) m[a+i][d]
3) m[c][d-i]
4) m[c-i][b]
public static void rotate(int[][] matrix){
int tR = 0;
int iC = 0;
int dR = matrix.length - 1;
int dC = matrix[0].length - 1;
while(tR < dR){
rotateEdge(matirx, tR++, tC++, dR--, dC--);
}
}
public static void rotateEdge(int[][] m, int a, int b, int c, int d){
int times = d - b;
int tmp = 0;
for (int i = 0; i != times; i++){
tmp = m[a][b + i];
m[a][b + i] = m[c - i][b];
m[c - i][b] = m[c][d - i];
m[c][d - i] = m[a + i][d];
m[a + i][d] = tmp;
}
}
Zigzag打印矩阵
public static void printMatrixZigzag(int[][] matrix){
int ar = 0;
int ac = 0;
int br = 0;
int bc = 0;
int endR = matrix.length - 1;
int endC = matrix[0].length - 1;
while(ar != endR + 1){
printLevel(matrix, ar, ac, br, bc, fromUp);
ar = ac == endC ? ar + 1 : ar;
ac = ac == endC ? ac : ac + 1;
bc = br == endR ? bc + 1 : bc;
br = br == endR ? br : br + 1;
fromUp = !fromUp;
}
System.out.println();
}
public static void printLevel(int[][] m, int tR, int tC, int dR, int dC, boolean f){
if(f){
while(tR != dR + 1){
System.out.print(m[tR++][tc--] + " ");
}
}else{
while(dR != tR - 1){
System.out.print(m[dR--][dC++] + " ");
}
}
}
题目三:假设s和m初始化, s = "a" ; m = s
再定义两种操作,第一种:
m = s;
s = s + s;
第二种操作:
s = s + m;
求最小的操作步骤数,可以将s拼接到长度等于n
如果n是质数,只调用操作二达到的步骤数是最少步骤数
操作1是有因子的
n不是质数,假设n由某些质数因子构成,假设一个最优顺序n = x* y * z* p
搞定x * y * z 之后 ,调用p -1 次操作二
所以是x+y+z+p-4
//请保证n不是质数
//返回:
//0) 所有因子的和,但是因子不包括1
//1) 所有因子的个数,但是因子不包括1
public static int[] divsSumAndCount(int n){
int sum = 0;
int count = 0;
for(int i = 2; i <= n; i++){
while(n % i == 0){
sum += i;
conut++;
n /= i;
}
}
return new int[] {sum, count};
}
public static int minOps(int n) {
if (n < 2){
return 0;
}
if (isPrim(n)){
return n - 1;
}
//n不是质数
int[] divSumAndCount = divsSumAndCount(n);
return divSumAndCount[0] - divSumAndCount[1];
}
题目四:给一个数组,出现次数前K的字符串
词频表(key字符串,value词频)
堆(大根堆/小根堆(门槛))
扩展:设计结构,这个结构可以接受用户给的字符串add(str),且可以随时显示目前排名前k的字符串void printTopK()(动态结构)
思路:改堆
词频表(key 字符串, value 词频)
堆[初始k个长度] heapsize = 0;
记录某个字符串在堆上的位置 map(key 字符串 , value 位置)
public static class Node{
public String str;
public int times;
public Node(String s, int t){
public String str;
public int times;
public Node(String s, int t){
str = s;
times = t;
}
}
public static class TopKRecord{
private HashMap<String, Node> strNodeMap;
private Node[] heap;
private int index;
private HashMap<Node, Integer> nodeIndexMap;
public TopKRecord(int size){
heap = new Node[size];
index = 0;
strNodeMap = new HashMap<String, Node>();
nodeIndexMap = new HashMap<Node, Integer>();
}
public void add(String str){
//当前str对应的节点对象
Node curNode = null;
//当前str对应的节点对象是否在堆上
int preIndex = -1;
if (!strNodeMap.containsKey(str)){//第一次出现
curNode = new Node(str, 1);
strNodeMap.put(str, curNode);
nodeIndexMap.put(curNode, -1);
}else{ // 并非第一次出现
curNode = strNodemap.get(str);
curNode.times++;
preIndex = nodeIndexMap.get(curNode);
}
if (preIndex == -1){//当前str对应的节点对象,词频增加后不在堆上
if(index == heap.length){
if(heap[0].times < curNode.times){
nodeIndexMap.put(heap[0], -1);
nodeIndexMap.put(curNode, 0);
heap[0] = curNode;
heapify(0, index);
}
} else {
nodeIndexMap.put(curNode, index);
heap[index] = curNode;
heapInsert(index++);
}
}else {
heapify(preIndex, index);
}
}
public void printTopK(){
System.out.println("TOP: ");
for (int i = 0; i != heap.length; i++){
if(heap[i] == null){
break;
}
System.out.print("Str: " + heap[i].str);
Ststem.out.prinln("Times: " + heap[i].times);
}
}
}
}