[카테고리:] 생활코딩

  • 프로그래머스 예산

    프로그래머스 예산

    정확성은 다 맞는데, 효율성이 떨어진다. 효율성 2번, 3번은 도대체 어떻게 할지 모르겠다. 또한 효율성 통과 기준이 너무 높다. 19ms는 충분히 빠르다. 반드시 이분 탐색으로 풀어야 효율성 테스트를 통과하는 듯 하다. 정확성은 좀 쉬운데, 효율성 테스트가 또 마의 영역이다.

    이 문제에서 이분 탐색을 어떻게 활용해야되는지 모르겠다. 너무 많이 진행되어 엎을 수 없어 보완했다.

    
    import java.util.Arrays;
    
    public class Bugdet {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Solution sol = new Solution();
    		int[] budgets = { 120, 110, 140, 150 };
    		int M = 485;
    		int answer = 0;
    		answer = sol.solution(budgets, M);
    		System.out.println("테스트: " + answer);
    
    	}
    
    }
    
    class Solution {
    	public int solution(int[] budgets, int M) {
    		//배열을 오름차순 정렬.
    		Arrays.sort(budgets);
    		/*
    		 * for (int i = 0; i < budgets.length; i++) System.out.println(budgets[i]);
    		 */
    		int t = budgets[budgets.length - 1];
    		int k = 0;
    		long answer = 0;
    		int tempSum = M + 1;
    		while (tempSum > M) {
    			answer = t;
    			tempSum = sum(budgets, k, t);
    			k = Arrays.binarySearch(budgets, t);
    
    			if (k < 0)
    				k = -(k + 1);
    			k = budgets.length - k;
    			if (sum(budgets, k + 1, budgets[budgets.length - k - 1]) >=M)
    				t = budgets[budgets.length - k - 1];
    			else
    				t = t - 1;
    
    		} //while
    		/*
    		 * for (int i = 0; i < budgets.length; i++) { int tempSum = sum(budgets, k, t);
    		 * if (tempSum <= M) { answer = t; break; } else { t = t - 1; k =
    		 * Arrays.binarySearch(budgets, t); if (k < 0) k = -(k + 1); k = budgets.length
    		 * - k; } answer = t; }
    		 */
    		return (int)answer;
    	}
    
    	public int sum(int[] budgets, int k, int t) {
    		int tempSum = 0;
    		for (int i = 0; i < budgets.length - k; i++) {
    			tempSum = tempSum + budgets[i];
    		}
    		//		for (int j = 0; j < k; j++)
    		//			tempSum = tempSum + t;
    
    		tempSum = tempSum + k * t;
    		return tempSum;
    
    	}
    
    }

  • 프로그래머스 2xn 타일링

    문제를 읽으면 어렵다. 출제자 기준에서 생각한다면, 답이 큰 수임을 보고 수열을 묻는 문제임을 알아야 한다. 이 바닥에서 유명한 피보나치 수열을 묻는 문제라고 눈치채야 한다.

    public class Main {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Solution sol = new Solution();
    		int n = 0;
    		for (int i = 0; i < 100; i++) {
    			n = sol.solution(i);
    			System.out.println("i는 " + i + ", n은" + n);
    		}
    
    	}
    
    }
    
    class Solution {
    	public static int solution(int n) {
    		int a = 1, b = 2, c = 0;
    		if (n == 0)
    			return 1;
    		else if (n < 2)
    			return n;
    
    		for (int i = 2; i < n; i++) {
    			c = b;
    			b = (a + b) % 1000000007;
    			a = c;
    
    		}
    		return b;
    	}
    }
  • 프로그래머스 베스트앨범

    내가 너무 어렵게 푸나? 다른 사람 코드는 쉽던데. 이 문제가 java Collection framework를 아는지 물어본다. 물론 난 잘 모르지만.

    
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.TreeMap;
    
    public class Main {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		// 시작..
    		//		String[] operations = { "I16", "I10", "I20", "D1" };
    
    		String[] genres = { "classic", "pop", "classic", "classic", "pop" };
    		int[] plays = new int[] { 500, 600, 150, 800, 2500 };
    		Solution sol = new Solution();
    		int[] answer = new int[10];
    		answer = sol.solution(genres, plays);
    		System.out.println("답은"+answer);
    
    	}
    }
    
    class Solution {
    	public int[] solution(String[] genres, int[] plays) {
    		int[] answer;
    		TreeMap<String, Integer> genresSelcetion = new TreeMap<>();
    		TreeMap<Integer, Integer> genresIndex = new TreeMap<>();
    		ArrayList<Integer> bestAlbum = new ArrayList<>();
    
    		for (int i = 0; i < genres.length; i++) {
    			int count = 0;
    			//			count = genresSelcetion.get(genres[i]);
    			if (genresSelcetion.get(genres[i]) == null) {
    				//genres가 없음.
    				genresSelcetion.put(genres[i], plays[i]);
    				//				System.out.println("String은" + genres[i]);
    			} else { //genres가 있음.
    				count = genresSelcetion.get(genres[i]);
    				genresSelcetion.put(genres[i], count + plays[i]);
    
    			}
    			System.out.println("카운트" + count);
    		}
    
    		//TreeMap 왼쪽 정렬.
    		Comparator<String> comparator = new ValueComparator<String, Integer>(genresSelcetion);
    		TreeMap<String, Integer> sortedGenresSelection = new TreeMap<>(comparator);
    		sortedGenresSelection.putAll(genresSelcetion);
    		Iterator<String> itrGenres = sortedGenresSelection.keySet().iterator();
    
    		//입력된 String[] genres - key, 곡 index - value로 만듦.
    		while (itrGenres.hasNext()) {
    			String key = itrGenres.next();
    			System.out.println("Key=" + key);
    			for (int i = 0; i < genres.length; i++) {
    				if (genres[i].equals(key)) {
    					genresIndex.put(i, plays[i]);
    					System.out.println("No" + i + " is genres=" + genres[i] + ", plays =" + plays[i]);
    					//넣을때 정렬.
    				}
    
    				System.out.println("전체 value은" + genresIndex.values());
    			} //for
    				//한 장르 모두 끝난 후, 값으로 정렬
    				//다시 사용하기 위해 loop 안에서 선언
    			Comparator<Integer> comparator2 = new ValueComparator<Integer, Integer>(genresIndex){
    
    				@Override
    				public int compare(Integer arg0, Integer arg1) {
    					// TODO Auto-generated method stub
    					return map.get(arg0)> map.get(arg1)?-1:1;
    
    				}
    				
    				
    			};
    			TreeMap<Integer, Integer> sortedGenresIndex = new TreeMap<>(comparator2);
    			sortedGenresIndex.putAll(genresIndex);
    			Iterator<Integer> itrGenresIndex = sortedGenresIndex.keySet().iterator();
    			int j = 0;
    			while (itrGenresIndex.hasNext()) {
    				//정리한 순서를 Array List에 삽입
    				Integer playIndex = itrGenresIndex.next();
    				j++;
    				if (j > 2)
    					break;
    				bestAlbum.add(playIndex);
    			}
    
    			System.out.println("여기 확인!! value은" + sortedGenresIndex.values());
    			for (int k = 0; k < bestAlbum.size(); k++)
    				System.out.println("여기는 ArrayList" + bestAlbum.get(k));
    
    			//clear TreeMap..
    			sortedGenresIndex.clear();
    			genresIndex.clear();
    
    		} // while
    		/*
    		 * while (itrGenres.hasNext()) {
    		 * 
    		 * Object key = itrGenres.next(); System.out.println("key는" + key);
    		 * System.out.println("value는" + sortedGenresSelection.get(key));
    		 * 
    		 * }
    		 * 
    		 */
    		//		System.out.println("전체 value은" + sortedGenresSelection.values());
    
    		answer = new int[bestAlbum.size()];
    		for (int l = 0; l < bestAlbum.size(); l++) {
    			answer[l] = bestAlbum.get(l);
    
    		}
    		return answer;
    
    	}
    
    }//Solution
    
    class ValueComparator<K, V extends Comparable<V>> implements Comparator<K> {
    	TreeMap<K, V> map = new TreeMap<K, V>();
    
    	public ValueComparator(TreeMap<K, V> map) {
    		this.map.putAll(map);
    	}
    
    	@Override
    	public int compare(K arg0, K arg1) {
    		// TODO Auto-generated method stub
    		return -map.get(arg0).compareTo(map.get(arg1));
    	}
    
    } //class ValueComparator

    TreeMap Value로 정렬

    keyset, entryset 차이

    java8 이후로 추가된 treemap 정렬

  • 프로그래머스 이중우선큐

    아래처럼하면 될듯하다.

    위 방법대로 하려다 잘 안된다. max 큐에서 min큐로 변경될 때 연산이 하나씩 틀어진다. 결국 max queue를 poll하면 min queue를 클리어하고, max queue로 업데이트 했다.

    
    import java.util.Collections;
    import java.util.regex.*;
    import java.util.PriorityQueue;
    
    public class Main {
    
    	public static void main(String[] args) {
    		// 시작..
    		//		String[] operations = { "I16", "I10", "I20", "D1" };
    		String[] operations = { "I -45", "I 653", "D 1", "I -642", "I 45", "I 97", "D 1", "D -1", "I 333" };
    
    		Solution sol = new Solution();
    		int[] t = sol.solution(operations);
    		System.out.println(t[0]+","+ t[1]);
    	}// void main
    
    }
    
    class Solution {
    	public int[] solution(String[] operations) {
    		Pattern tmpNumber = Pattern.compile("(-[0-9]{1,}|[0-9]{1,})");
    		PriorityQueue<Work> pqMax = new PriorityQueue<>();
    		PriorityQueue<Work> pqMin = new PriorityQueue<>(Collections.reverseOrder());
    
    
    		for (int in = 0; in < operations.length; in++) {
    			//			System.out.println("인자: " + operations[in] + operations[in]);
    			String op = operations[in].substring(0, 1);
    			//정규표현식으로 숫자만 출력.
    			Matcher tmpMatcher = tmpNumber.matcher(operations[in]);
    			String tmpNum = "";
    			Integer num = 0;
    			//			int num = Integer.parseInt(tmpMatcher.group());
    			while (tmpMatcher.find()) {
    				tmpNum = tmpMatcher.group();
    				//				System.out.println(tmpMatcher.group());
    			}
    			num = Integer.parseInt(tmpNum);
    			//			System.out.println(num);
    			//			System.out.println(tmpMatcher.find());
    
    			//			int num = Integer.parseInt(operations[in + 1]);
    			if (op.equals("I")) {
    
    				pqMax.add(new Work(num));
    				pqMin.add(new Work(num));
    
    			} else if (op.equals("D"))
    				if (num.equals(1)) {
    					pqMax.poll();
    					if (pqMax.size() == 0)
    						//size가 0이면 마지막 1개를 취출했음.
    						pqMin.poll();
    					else {
    						pqMin.clear();
    						pqMin.addAll(pqMax);
    					}
    				} else if (num.equals(-1)) {
    					pqMin.poll();
    					if (pqMin.size() == 0)
    						//size가 0이면 마지막 1개를 취출했음.
    						pqMax.poll();
    					else {
    						pqMax.clear();
    						pqMax.addAll(pqMin);
    					}
    
    				}
    
    		}
    
    		/*
    		 * System.out.println("Max 큐"); while (!pqMax.isEmpty()) {
    		 * System.out.println(pqMax.poll().number); }
    		 * 
    		 * System.out.println("Min 큐"); while (!pqMin.isEmpty()) {
    		 * System.out.println(pqMin.poll().number); }
    		 */
    
    		int[] answer = new int[2];
    		if (pqMax.size() != 0)
    			answer[0] = pqMax.poll().number;
    		else
    			answer[0] = 0;
    		if (pqMin.size() != 0)
    			answer[1] = pqMin.poll().number;
    		else
    			answer[1] = 0;
    
    		return answer;
    	} //solution
    
    }
    
    class Work implements Comparable<Work> {
    	int number;
    
    	Work(Integer num) {
    		this.number = num;
    	}
    
    	@Override
    	public int compareTo(Work arg0) {
    		// TODO Auto-generated method stub
    
    		return this.number > arg0.number ? -1 : 1;
    	}
    
    }
  • 프로그래머스 디스크컨트롤러

    웹에 올린 결과는 틀림. 그러나 내가 맞다 생각한다.

    문제는 아래와 같다.

    1. 작업이 [시작 시각, 작업 길이] 2차원 배열로 들어온다.
    2. 작업이 연속될 경우, 이 안에서 작업 길이를 짧은 순으로 정렬하여 실행한다.
    3. 각 작업에 대한 기다린 시간 + 작업 시간을 계산한다.
    4. 작업 개수를 총 시간으로 나눠준다.

    여기에서 배열을 한번에 읽는다. 첫번째 작업 순서를 읽을 때, 모든 작업 순서를 결정할 수 있다. 예제 [[0, 3], [1, 9], [2, 6]] 순서에 마지막 2개를 더 들어온다고 하자. [[0, 3], [1, 9], [2, 6], [24,4], [20,7]].

    엑셀 Calc로 그림을 그리면 아래와 같다.

    작업A부터 작업E까지 읽을 때, 필요한 작업 시간(checkBar)을 정해야 한다. 이 작업 시간안에 들어오면 작업 시간을 적은 순서대로 정렬한다. 작업 시간을 넘어가면 다음 턴에 정렬해야 한다.

    입력을 읽을 때, 24초에 들어온 작업과 20초에 들어온 작업을 결정할 수 있다. 다음과 같이 조정할 수 있다. 24초에 들어온 작업을 20초에 먼저 실행하면 작업D, 작업E를 하는데 총 11초 걸린다.

    만약 들어온 순서대로 하면 작업D, 작업E를 14초에 한다. jobs을 읽을 때 뒤쪽 배열에 시간이 빠른 작업을 어떻게 처리할까? 이런 경우를 보면 jobs을 순서대로 읽으면 안된다. 모두 읽어서 빠른 순서대로 정리해야 한다.

    하드 디스크가 놀고 있을 때 먼저 들어온 순서대로 한다는 제한이 있다. jobs[][]이 대기열이다. 현재 시각이 0초이고, jobs[0] = [1,2], jobs[1] = [2,5], jobs[2] = [0,4]이라 하자. 위 제한에 따르면 jobs[2]는 조정할 수 없어 실핼할 수 없다. 문제 조건에 jobs[i]는 항상 시작 시각이 늘어난다는 조건을 추가해야 한다. 이 조건이 있었으면 내가 이런 개고생 안했을 수 있었다. 웹은 틀렸다지만 난 맞았다고 정당화시키고 끝낸다.

    문제는 이 코드를 웹에 올리면 runtime error로 검증할 수 없다. 우선순위 큐 문제에 너무 많은 시간을 보냈다.

    
    import java.util.Collections;
    import java.util.PriorityQueue;
    
    public class Main {
    	public static void main(String[] args) {
    
    		//		PriorityQueue<Student> ptrTestQ = new PriorityQueue<>();
    
    		//		while (!sol.getQ().isEmpty())
    		//			System.out.println(ptrTestQ.remove());
    
    		// 시작..
    		int[][] jobs = new int[5][2];
    		jobs[0][0] = 0;
    		jobs[0][1] = 3;
    		jobs[1][0] = 1;
    		jobs[1][1] = 9;
    		jobs[2][0] = 2;
    		jobs[2][1] = 6;
    		jobs[3][0] = 24;
    		jobs[3][1] = 4;
    		jobs[4][0] = 20;
    		jobs[4][1] = 7;
    
    		/*
    		 * System.out.println("Jobs type은"+jobs.getClass().getTypeName());
    		 * 
    		 * 
    		 */
    		Solution sol = new Solution();
    		int answer = sol.solution(jobs);
    
    		System.out.println("여기");
    		System.out.println("답은  " + answer);
    
    		/*
    		 * while (!sol.getQue().isEmpty()) System.out.println("sol.getQue내용은 " +
    		 * sol.getQue().poll()); while (!sol.getQueOffset().isEmpty())
    		 * System.out.println("sol.getQueOffset내용은 " + sol.getQueOffset().poll());
    		 */
    
    	}// void main
    
    } // Main
    
    class Solution {
    
    	public int solution(int[][] jobs) {
    
    		// 요청 대기시간이 보정된 큐.
    		PriorityQueue<Job> priqueJobsReversed = new PriorityQueue<>();
    		PriorityQueue<Job> priqueCheckReversed = new PriorityQueue<>();
    
    		// jobs을 class로 입력
    		for (int i = 0; i < jobs.length; i++) {
    			Job tmpJob = new Job(jobs[i][0], jobs[i][1]);
    			// timeStamp 기준 정렬
    			// setFlag와 세트로 같이 움직여야 됨.
    			priqueJobsReversed.add(tmpJob);
    		}
    		/*
    		 * while (!priqueJobsReversed.isEmpty()) { System.out.println("timeStamp:" +
    		 * priqueJobsReversed.peek().timeStamp + ", Duration: " +
    		 * priqueJobsReversed.peek().duration); priqueJobsReversed.poll(); }
    		 */
    
    		PriorityQueue<Job> priqueJobs = new PriorityQueue<>(priqueJobsReversed.size(), Collections.reverseOrder());
    		priqueJobs.addAll(priqueJobsReversed);
    
    		// 복사..
    		PriorityQueue<Job> priqueJobsTmp = new PriorityQueue<>(priqueJobs);
    
    		boolean overlapped = false;
    		int startTime = 0;
    		int endTime = 0;
    		int preDuration = 0;
    		int preTimeStamp = 0;
    		int PolledDuration = 0;
    		int PolledTimeStamp = 0;
    		while (!priqueJobsTmp.isEmpty()) {
    			if (!overlapped) {
    				startTime = priqueJobsTmp.peek().timeStamp;
    				endTime = startTime + priqueJobsTmp.peek().duration;
    
    			}
    			preDuration = priqueJobsTmp.peek().duration;
    			preTimeStamp = priqueJobsTmp.peek().timeStamp;
    			priqueJobsTmp.poll();
    			if (!priqueJobsTmp.isEmpty()) {
    				PolledDuration = priqueJobsTmp.peek().duration;
    				PolledTimeStamp = priqueJobsTmp.peek().timeStamp;
    			} //if
    			else {
    				PolledTimeStamp = 0;
    				Job checkBar = new Job(startTime, endTime);
    				// 시간순으로 정렬
    				priqueCheckReversed.add(checkBar);
    
    			}
    			if (startTime + preDuration >= PolledTimeStamp) {
    				// overlapped를 true로 바꾸고, endTime을 연장
    				overlapped = true;
    				endTime = endTime + PolledDuration;
    
    			} //if
    			else {
    				// endTime 연장하지 않음.
    				// overlapped flag를 다시 false로 변경.
    				overlapped = false;
    				// 여기에서 priorityQueue에 넣음.
    				Job checkBar = new Job(startTime, endTime-1);
    				// 시간순으로 정렬
    				priqueCheckReversed.add(checkBar);
    
    			} // else
    				//			System.out.println("현재 startTime" + startTime);
    				//			System.out.println("현재 endTime" + endTime);
    				//			Object[] testArry = priqueCheckReversed.toArray();
    
    		} // while
    		/*
    		 * System.out.println("*****여기 확인*******"); while (!priqueJobsTmp.isEmpty())
    		 * System.out.println(priqueJobsTmp.poll());
    		 */
    
    		// 거꾸로 만든 큐 순서를 뒤집음.
    
    		PriorityQueue<Job> priqueCheck = new PriorityQueue<>(priqueCheckReversed.size(), Collections.reverseOrder());
    		priqueCheck.addAll(priqueCheckReversed);
    		//		System.out.println("큐 크기" + priqueCheckReversed.size());
    
    		int answer = 0;
    
    		PriorityQueue<Job> priqueJobsOder = new PriorityQueue<Job>();
    
    		int i = 1;
    		while (!priqueCheck.isEmpty()) {
    			// 시작시각 확인.
    			int startTimeCheck = priqueCheck.peek().timeStamp;
    			int endTimeCheck = priqueCheck.peek().duration;
    			int presentTime = priqueCheck.peek().timeStamp;
    			//check구간의 Jobs을 꺼낸 후, 우선순위 변경하여 다시 넣어줌.
    			while (!priqueJobs.isEmpty()) {
    				int tmpTimeStamp = priqueJobs.peek().timeStamp;
    				int tmpDuration = priqueJobs.peek().duration;
    				if (startTimeCheck <= tmpTimeStamp && tmpTimeStamp <= endTimeCheck) {
    					Job orderJob = new Job(tmpTimeStamp, tmpDuration);
    					orderJob.setFlag(true);
    					priqueJobsOder.add(orderJob);
    					priqueJobs.poll();
    				} // if
    				else
    					break;
    
    			} //while priqueJobs
    
    			//한턴 끝난 후 reverse order로 변경.
    			PriorityQueue<Job> priqueJobsOderNext = new PriorityQueue<>(priqueJobsOder.size(),
    					Collections.reverseOrder());
    			priqueJobsOderNext.addAll(priqueJobsOder);
    
    			while (!priqueJobsOderNext.isEmpty()) {
    
    				int delay = presentTime - priqueJobsOderNext.peek().timeStamp;
    				int tmpAnswer = delay + priqueJobsOderNext.peek().duration;
    				answer = answer + tmpAnswer;
    				System.out.println("answer = " + answer);
    				System.out.println("현재시각 = " + presentTime);
    				System.out.println("duration = " + priqueJobsOderNext.peek().duration);
    				System.out.println("delay = " + delay);
    
    				i++;
    				presentTime = presentTime + priqueJobsOderNext.peek().duration;
    				priqueJobsOderNext.poll();
    				priqueJobsOder.poll();
    			} //while (priqueHobsOrderNext)
    
    			priqueCheck.poll();
    
    		} //while priqueCheck
    
    		answer = answer / (i - 1);
    		return answer;
    	}// int solutions(int[][] jobs)
    
    }
    
    class Job implements Comparable<Job> {
    	int duration;
    	int timeStamp;
    	boolean flag;
    
    	// 기본 생성자.
    	Job() {
    		this.duration = 0;
    		this.timeStamp = 0;
    		this.flag = false;
    	}
    
    	// 생성자 작성.
    	Job(int timeStamp, int duration) {
    		this.timeStamp = timeStamp;
    		this.duration = duration;
    		this.flag = false;
    
    	}
    
    	@Override
    	public int compareTo(Job arg0) {
    		// TODO Auto-generated method stub
    		if (!this.flag)
    			// TimeStamp가 큰 순서대로 poll;
    			return this.timeStamp < arg0.timeStamp ? 1 : -1;
    		else
    			// Duration이 큰 순서대로 poll
    			return this.duration < arg0.duration ? 1 : -1;
    
    	}
    
    	@Override
    	public String toString() { // TODO Auto-generated method stub
    		return "시각" + this.timeStamp + ", 기간" + this.duration;
    	}
    
    	public void setFlag(boolean flag) {
    		this.flag = flag;
    
    	}
    
    } // Job