一位老师正在出一场由 n 道判断题构成的考试,每道题的答案为 true (用 'T' 表示)或者 false (用 'F' 表示)。老师想增加学生对自己做出答案的不确定性,方法是 最大化 有 连续相同 结果的题数。(也就是连续出现 true 或者连续出现 false)。
给你一个字符串 answerKey ,其中 answerKey[i] 是第 i 个问题的正确结果。除此以外,还给你一个整数 k ,表示你能进行以下操作的最多次数:
每次操作中,将问题的正确答案改为 'T' 或者 'F' (也就是将 answerKey[i] 改为 'T' 或者 'F' )。
请你返回在不超过 k 次操作的情况下,最大 连续 'T' 或者 'F' 的数目。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
———————————————————————————————————————————
day10:第十天的代码,因为有事情耽搁了一直没发博客,今天补上博客,读完题目学过c的应该很明白,双向指针,或者学过数据结构会想到双向队列,我开始就测试了双向队列,效果不怎么好,还得看数组加双向指针,又快又准,看看代码:
public int maxConsecutiveAnswers(String answerKey, int k) { return Math.max(maxConsecutiveChar0(answerKey, k, 'T'), maxConsecutiveChar0(answerKey, k, 'F')); } public int maxConsecutiveChar(String answerKey, int k, char c){ Deque<Character> deque = new LinkedList<>(); int size = answerKey.length(), sum = 0, ans = 0; for (int i = 0; i < size; i++) { char chr = answerKey.charAt(i); if (c == chr) sum ++ ; deque.add(chr); while (sum > k) { if ( deque.pollFirst() == c ) sum -= 1; } ans = Math.max(ans, deque.size()); } return ans; }
思路解析:通过构建一个双向队列,这样就可以一直往里加,当个数超过k了就把最前面的抛出,直到不超过k(也就是判断更换最多T或者F最后在队列中能存放的值),通过for循环遍历整个字符串,取每一个值来给c判断,如果我们要更换T,则当当前值为T时,记录队列中T的个数,如果队列中T的个数比k多了,就要一直抛出最前面的直到队列中T的个数不比k多,然后用一个ans来记录最多的个数并返回,再算F的,最终比较最大值得到结果
这种方法比较慢,速度和内存都只能超过百分之几,于是有了下列方法:
public int maxConsecutiveAnswers1(String answerKey, int k) { return Math.max(maxConsecutiveChar1(answerKey, k, 'T'), maxConsecutiveChar1(answerKey, k, 'F')); } public int maxConsecutiveChar1(String answerKey, int k, char ch) { int n = answerKey.length(); int ans = 0; for (int left = 0, right = 0, sum = 0; right < n; right++) { sum += answerKey.charAt(right) != ch ? 1 : 0; while (sum > k) { sum -= answerKey.charAt(left++) != ch ? 1 : 0; } ans = Math.max(ans, right - left + 1); } return ans; }
思路解析:方法一致,只是通过right和left来记录指针,先用right来一直遍历,再通过left来抛出最前面的字符,方法是一致的,只是没使用容器来存储,于是速度和内存都快了很多,这次达到了速度四十左右,内存二十左右,再变形:
public int maxConsecutiveAnswers(String answerKey, int k) { char[] ans = answerKey.toCharArray(); return Math.max(get(ans,'T',k),get(ans,'F',k)); } public int get(char[] ans,char aim,int k){ int count = 0,l = 0, r = 0; while( r < ans.length ){ if(ans[r++] != aim) count++; if(count > k){ if(ans[l++] != aim) count--; } } return r - l; }
思路解析:这种通过直接变成数组,就不需要每次调用charAt方法来获取了,也是通过r和l来记录左右指针,跟上面差不多就不过多解释了,速度和内存达到了八十和五十
原文链接:https://blog.csdn.net/wqndxjr/article/details/123866312