做事贵在坚持,自律,每天认真刷一道题,坚持不懈,一定引起质变。
今天晚上回到家都10点多了,想着一定要每天刷一道题,周日偷懒了,今天不能给自己找借口啦。
题干
https://leetcode.com/problems/elimination-game/
给一串 1到 n的数列,然后从左到右隔一个删一个,剩下的部分再从右到左隔一个删一个,问最后剩下来的是谁?
思考过程
说实话看到这个题有点懵,有点恶心,但是有种很典型题的感觉,所以必须攻克。通过观察发现规律性:
1,每次删除操作后,每次剩下来的都是一个等差数列,等差数列的差是每次乘以2增长的,
2,每次删除操作后,剩下的最左边和最右边可以根据 当前数列的差,当前的最左边和最右边算出来,
3,最后剩下的值 曾经也当过最右边或最左边
解答
class Solution { /** * 按行数从上到下进行遍历 */ public static int lastRemaining(int n) { int left = 1, right = n; int thisLineDiff = 1;//当前的行数数字之前的差值 boolean direction = true;//从左到右 while (left < right) { int nextLineDiff = thisLineDiff * 2; if ((right - left) % nextLineDiff == 0) { //两遍的头都要删 left = left + thisLineDiff; right = right - thisLineDiff; } else { if (direction) { left += thisLineDiff; if (left > right) { return right; } } else { right -= thisLineDiff; if (right < left) { return left; } } } direction = !direction; thisLineDiff *= 2; } return left; } public static void main(String[] args) { int i = lastRemaining(16); System.out.println(i); } }
就是循环就好啦,处理好边界问题,不难,关键是能够深入进去思考,不入虎穴,焉得虎子,深入进去思考是一件很违反天性的事,但是答案往往就缺乏那一点深入,有痛苦才有提高。